In [ ]:
 
  • CLIP (Contrastive Language-Image Pretraining) est un modèle développé par OpenAI qui apprend à associer des images et des descriptions textuelles.
  • Pour tester une tâche de classification en 7 catégories en utilisant CLIP pour des textes et des images, l'idée est d'utiliser les représentations encodées par CLIP pour les images et les textes, puis d'entraîner un classificateur sur ces représentations.

+++ LIENS DE DOCUMENTTIONS

IMPORTS LIBRAIRIES¶

In [4]:
# data & science
import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix

# system & tools
import time
import os
import random

# graphiques
import matplotlib.pyplot as plt
from matplotlib.image import imread
import seaborn as sns
from wordcloud import WordCloud
%matplotlib inline

# natural language processing
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import RegexpTokenizer

# computer vision / CNN
from PIL import Image
import cv2 # OpenCV 

# computer vision / CNN
import tensorflow as tf
print("tensorflow", tf.__version__)
# TensorFlow utilise un seul thread pour garantir la reproductibilité
tf.config.threading.set_intra_op_parallelism_threads(1)
tf.config.threading.set_inter_op_parallelism_threads(1)
import keras
print("keras", keras.__version__)
from keras.applications import DenseNet121   
tensorflow 2.16.2
keras 3.6.0

Reproductibilité des résultats¶

In [5]:
# Seed value
seed_value= 1802

# 1. Set the `PYTHONHASHSEED` environment variable at a fixed value
os.environ['PYTHONHASHSEED']=str(seed_value)
print("os.environ['PYTHONHASHSEED'] == ", os.environ['PYTHONHASHSEED'])

# 2. Set the `python` built-in pseudo-random generator at a fixed value
random.seed(seed_value)

# 3. Set the `numpy` pseudo-random generator at a fixed value
np.random.seed(seed_value)

# 4. Set the `tensorflow` pseudo-random generator at a fixed value
tf.random.set_seed(seed_value)
tf.keras.utils.set_random_seed(seed_value) 

# 5. Configuration spécifique liée à l'utilisation des GPUs
## rapport de bug : "GPU MaxPool gradient ops do not yet have a deterministic XLA implementation" https://github.com/tensorflow/tensorflow/issues/69417
## I have the same problem about MaxPooling2D. The following tutorial about reproducibility of keras confirmed that the same error occurs: https://keras.io/examples/keras_recipes/reproducibility_recipes/
## I wrote this guide when Keras had jit_compile = None (Keras 2 or tf-keras) in the compile method. Now, Keras 3 uses jit_compile = "auto" (trying to use XLA) for the TensorFlow backend, which is the root of the error.
## You can simply pass jit_compile = False if you're using Keras 3.
tf.config.experimental.enable_op_determinism() # se trouve dans la partie API expérimental (call temporaire) depuis juin 2024, remplace os.environ['TF_DETERMINISTIC_OPS']  
# => dans modele.compile mettre jit_compile=False "just in time compiler"

# 6. Vérifier la reproductibilité
random_values_1 = tf.random.uniform([5], seed=seed_value)
print("TF/KERAS Valeurs aléatoires 1:", random_values_1.numpy())
tf.random.set_seed(seed_value)
tf.keras.utils.set_random_seed(seed_value) 
random_values_2 = tf.random.uniform([5], seed=seed_value)
print("TF/KERAS Valeurs aléatoires 2:", random_values_2.numpy())
assert np.array_equal(random_values_1.numpy(), random_values_2.numpy()), "TF/KERAS Les valeurs aléatoires ne sont pas identiques"
print("TF/KERAS Les valeurs aléatoires sont identiques, la graine est correctement fixée.")
os.environ['PYTHONHASHSEED'] ==  1802
TF/KERAS Valeurs aléatoires 1: [0.43668258 0.59952414 0.27555966 0.6870636  0.05337238]
TF/KERAS Valeurs aléatoires 2: [0.43668258 0.59952414 0.27555966 0.6870636  0.05337238]
TF/KERAS Les valeurs aléatoires sont identiques, la graine est correctement fixée.

DATA¶

  • charger et préparer les données
In [6]:
data_0 = pd.read_csv("./Flipkart/flipkart_com-ecommerce_sample_1050.csv")
data_0.info()
display(data_0.tail(1))
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1050 entries, 0 to 1049
Data columns (total 15 columns):
 #   Column                   Non-Null Count  Dtype  
---  ------                   --------------  -----  
 0   uniq_id                  1050 non-null   object 
 1   crawl_timestamp          1050 non-null   object 
 2   product_url              1050 non-null   object 
 3   product_name             1050 non-null   object 
 4   product_category_tree    1050 non-null   object 
 5   pid                      1050 non-null   object 
 6   retail_price             1049 non-null   float64
 7   discounted_price         1049 non-null   float64
 8   image                    1050 non-null   object 
 9   is_FK_Advantage_product  1050 non-null   bool   
 10  description              1050 non-null   object 
 11  product_rating           1050 non-null   object 
 12  overall_rating           1050 non-null   object 
 13  brand                    712 non-null    object 
 14  product_specifications   1049 non-null   object 
dtypes: bool(1), float64(2), object(12)
memory usage: 116.0+ KB
uniq_id crawl_timestamp product_url product_name product_category_tree pid retail_price discounted_price image is_FK_Advantage_product description product_rating overall_rating brand product_specifications
1049 f2f027ad6a6df617c9f125173da71e44 2015-12-01 10:15:43 +0000 http://www.flipkart.com/uberlyfe-large-vinyl-s... Uberlyfe Large Vinyl Sticker ["Baby Care >> Baby & Kids Gifts >> Stickers >... STIE2ZEPACRQJKH7 1190.0 595.0 f2f027ad6a6df617c9f125173da71e44.jpg False Buy Uberlyfe Large Vinyl Sticker for Rs.595 on... 4 4 Uberlyfe {"product_specification"=>[{"key"=>"Sales Pack...

Les catégories principales¶

In [7]:
# Séparation de la catégorie principale et de ses sous-catégories
def extract_categories(row):
    categories = row.strip('["]').split(' >> ')
    categ_0 = categories[0]
    sub_categories = ' '.join(categories[1:]) 
    return categ_0, sub_categories
# Fonction pour obtenir les dimensions des images
def get_image_dimensions(image_path):
    image = cv2.imread(image_path)
    if image is not None:
        height, width, _ = image.shape
        return height, width
    else:
        return None, None  
In [8]:
prep_data = data_0.filter(['uniq_id', 'product_name', 'description', 'product_category_tree', 'image'])
# extraire la catégorie principale et les sous-catégories regroupées
prep_data[['categ_0', 'sub_categories']] = prep_data['product_category_tree'].apply(lambda x: pd.Series(extract_categories(x)))
prep_data['categ_0'] = prep_data['categ_0'].str.lower()
prep_data.tail(5)
Out[8]:
uniq_id product_name description product_category_tree image categ_0 sub_categories
1045 958f54f4c46b53c8a0a9b8167d9140bc Oren Empower Extra Large Self Adhesive Sticker Oren Empower Extra Large Self Adhesive Sticker... ["Baby Care >> Baby & Kids Gifts >> Stickers >... 958f54f4c46b53c8a0a9b8167d9140bc.jpg baby care Baby & Kids Gifts Stickers Oren Empower Stickers
1046 fd6cbcc22efb6b761bd564c28928483c Wallmantra Large Vinyl Sticker Sticker Wallmantra Large Vinyl Sticker Sticker (Pack o... ["Baby Care >> Baby & Kids Gifts >> Stickers >... fd6cbcc22efb6b761bd564c28928483c.jpg baby care Baby & Kids Gifts Stickers Wallmantra Stickers
1047 5912e037d12774bb73a2048f35a00009 Uberlyfe Extra Large Pigmented Polyvinyl Films... Buy Uberlyfe Extra Large Pigmented Polyvinyl F... ["Baby Care >> Baby & Kids Gifts >> Stickers >... 5912e037d12774bb73a2048f35a00009.jpg baby care Baby & Kids Gifts Stickers Uberlyfe Stickers
1048 c3edc504d1b4f0ba6224fa53a43a7ad6 Wallmantra Medium Vinyl Sticker Sticker Buy Wallmantra Medium Vinyl Sticker Sticker fo... ["Baby Care >> Baby & Kids Gifts >> Stickers >... c3edc504d1b4f0ba6224fa53a43a7ad6.jpg baby care Baby & Kids Gifts Stickers Wallmantra Stickers
1049 f2f027ad6a6df617c9f125173da71e44 Uberlyfe Large Vinyl Sticker Buy Uberlyfe Large Vinyl Sticker for Rs.595 on... ["Baby Care >> Baby & Kids Gifts >> Stickers >... f2f027ad6a6df617c9f125173da71e44.jpg baby care Baby & Kids Gifts Stickers Uberlyfe Stickers
In [9]:
# encoder le nom des catéories principales
le = LabelEncoder()
le.fit(prep_data["categ_0"])
prep_data["label"] = le.transform(prep_data["categ_0"])
prep_data.head(2)
Out[9]:
uniq_id product_name description product_category_tree image categ_0 sub_categories label
0 55b85ea15a1536d46b7190ad6fff8ce7 Elegance Polyester Multicolor Abstract Eyelet ... Key Features of Elegance Polyester Multicolor ... ["Home Furnishing >> Curtains & Accessories >>... 55b85ea15a1536d46b7190ad6fff8ce7.jpg home furnishing Curtains & Accessories Curtains Elegance Polye... 4
1 7b72c92c2f6c40268628ec5f14c6d590 Sathiyas Cotton Bath Towel Specifications of Sathiyas Cotton Bath Towel (... ["Baby Care >> Baby Bath & Skin >> Baby Bath T... 7b72c92c2f6c40268628ec5f14c6d590.jpg baby care Baby Bath & Skin Baby Bath Towels Sathiyas Bab... 0
In [10]:
label_to_category = {label: category for label, category in enumerate(le.classes_)}
label_to_category
Out[10]:
{0: 'baby care',
 1: 'beauty and personal care',
 2: 'computers',
 3: 'home decor & festive needs',
 4: 'home furnishing',
 5: 'kitchen & dining',
 6: 'watches'}

Les descriptions¶

  • S'assurer que toutes les descriptions sont en anglais, en regardant la présence de stopwords en anglais dans les textes.
In [11]:
# Télécharger les stop words
nltk.download('stopwords')
# Charger les stop words en anglais
stop_words = set(stopwords.words('english'))
[nltk_data] Downloading package stopwords to
[nltk_data]     /home/stephanie/nltk_data...
[nltk_data]   Package stopwords is already up-to-date!
In [12]:
# Fonction pour vérifier l'absence de stop words en anglais dans les descriptions
def sans_stopwords_anglais(text):
    words = text.split()
    return not any(word.lower() in stop_words for word in words)

# Filtrer les descriptions qui ne contiennent pas de stop words en anglais
filtered_data = prep_data[prep_data['description'].apply(sans_stopwords_anglais)]

# Afficher les descriptions qui ne contiennent pas de stop words en anglais
pd.set_option('display.max_colwidth', None)
print(filtered_data[['description']])
                                                                                                                                                                                                       description
89                     Parv Collections Showpiece  -  12 cm (Polyresin, Multicolor)\r\n                         Price: Rs. 1,085\r\n\t\t\t\t\r\n\t\t\tLovely Sitting Couple Statue\r\nLovely Sitting Couple Statue
116  Recrafto Buddha Showpiece  -  15.24 cm (Brass, Black, Green)\r\n                         Price: Rs. 3,500\r\n\t\t\t\t\r\n\t\t\tRecrafto Brass Buddha Religious Idols\r\nRecrafto Brass Buddha Religious Idols
267                              Sahara Q Shop Kadhai 1.5 L (Stainless Steel)\r\n                         Price: Rs. 650\r\n\t\t\t\t\r\n\t\t\tPremium Non Stick Kadhai 1.5.Ltr\r\nPremium Non Stick Kadhai 1.5.Ltr
599                                                                                Next Steps Baby Girl's Layered Dress\r\n                         Price: Rs. 356\r\n\t\t\t\t\r\n\t\t\tGirls Dress\r\nGirls Dress
881                 Sassoon Cotton Bath Towel (Red)\r\n                         Price: Rs. 1,299\r\n\t\t\t\t\r\n\t\t\tFerrari Printed Towel 75x150cm-Design No.472\r\nFerrari Printed Towel 75x150cm-Design No.472
930        Utsav Handicraft UHD004 Showpiece  -  8 cm (Silver Finish, Silver)\r\n                         Price: Rs. 899\r\n\t\t\t\t\r\n\t\t\tUtsav Handicraft Musical Ganesha\r\nUtsav Handicraft Musical Ganesha
  • sur l'ensemble des données il n'y a que 6 descriptions qui ne contiennent pas de stopwords en anglais.
  • il s'agit de rares exemples d'annonces très peu "verbeuses", écrites de manière très descriptives sans fioritures marketing. Ces textes sont néanmoins bel et bien anglais.
  • Nous pouvons affirmer que l'ensemble des textes est bien rédigé en anlgais.

Échantillons de descriptions par catégories

In [13]:
random_samples = prep_data.groupby('categ_0').apply(lambda x: x.sample(1, random_state=seed_value)).reset_index(drop=True)
for index, row in random_samples.iterrows():
    print(f" Exemple de description pour la catégorie ** {row['categ_0']} ** \n {row['description']} \n")
 Exemple de description pour la catégorie ** baby care ** 
 Key Features of cherry crumble california Baby Boy's Dungaree Fabric: 100% Cotton Brand Color: Grey Olive Camouflage,Specifications of cherry crumble california Baby Boy's Dungaree Top Details Fabric 100% Cotton Type Dungaree General Details Pattern Printed Ideal For Baby Boy's 

 Exemple de description pour la catégorie ** beauty and personal care ** 
 Vincent Valentine Paris Set of Dark Fire, Dark Fire & Majesty Deodorants Combo Set (Set of 3)
                         Price: Rs. 389
				
			Dark Fire sparkles with an enchanting top note blend of Black Currant and Star Anise. The distinctive spiciness is embraced by Galanga Root for depth and Green Pepper extract for warmth. The base is rich and woody with Balsam, Cedar entwined with Vanilla Beans. 
Passionate and royal, majesty, the latest beautiful perfume from Anna Andre distinguishes itself from all others. It pampers the young and extravagant woman with a neo-classical touch.
Dark Fire sparkles with an enchanting top note blend of Black Currant and Star Anise. The distinctive spiciness is embraced by Galanga Root for depth and Green Pepper extract for warmth. The base is rich and woody with Balsam, Cedar entwined with Vanilla Beans. 
Passionate and royal, majesty, the latest beautiful perfume from Anna Andre distinguishes itself from all others. It pampers the young and extravagant woman with a neo-classical touch. 

 Exemple de description pour la catégorie ** computers ** 
 Buy Binatone WR3000N only for Rs. 1800 from Flipkart.com. Only Genuine Products. 30 Day Replacement Guarantee. Free Shipping. Cash On Delivery! 

 Exemple de description pour la catégorie ** home decor & festive needs ** 
 Buy Rastogi Handicrafts Showpiece  -  20 cm for Rs.450 online. Rastogi Handicrafts Showpiece  -  20 cm at best prices with FREE shipping & cash on delivery. Only Genuine Products. 30 Day Replacement Guarantee. 

 Exemple de description pour la catégorie ** home furnishing ** 
 Specifications of JewelKraft Designs Brown, Pink Table Linen Set General Brand JewelKraft Designs Design Code MN Style Code 411 Color Brown, Pink In the Box Sales Package 6 table mats 6 napkins 

 Exemple de description pour la catégorie ** kitchen & dining ** 
 Buy Rajesh Digital BEST DAD 107 Ceramic Mug for Rs.250 online. Rajesh Digital BEST DAD 107 Ceramic Mug at best prices with FREE shipping & cash on delivery. Only Genuine Products. 30 Day Replacement Guarantee. 

 Exemple de description pour la catégorie ** watches ** 
 Disney 98189 Analog Watch  - For Boys, Girls - Buy Disney 98189 Analog Watch  - For Boys, Girls  98189 Online at Rs.900 in India Only at Flipkart.com. - Great Discounts, Only Genuine Products, 30 Day Replacement Guarantee, Free Shipping. Cash On Delivery! 

/tmp/ipykernel_911805/1082872909.py:1: DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.
  random_samples = prep_data.groupby('categ_0').apply(lambda x: x.sample(1, random_state=seed_value)).reset_index(drop=True)
In [14]:
# relimiter l'affichage des colonnes
pd.reset_option('display.max_colwidth')

Longueur des textes

In [15]:
# Test de tokenisation 
# \b\w*[a-zA-Z]+\w*\b correspond aux mots et aux chiffres collés à des lettres, sans les ponctuations
# \b[a-zA-Z]+\b correspond aux mots seuls, les chiffres sans lettres sont exclus    
tokenizer = RegexpTokenizer(r'\b\w*[a-zA-Z]+\w*\b|\b[a-zA-Z]+\b')

# Fonction pour compter le nombre de tokens dans une description
def count_tokens(text):
    tokens = tokenizer.tokenize(text)
    return len(tokens)

prep_data['token_count'] = prep_data['description'].apply(count_tokens)

# boxplot par catégories
plt.figure(figsize=(12, 6))
ax = sns.boxplot(x='categ_0', y='token_count', data=prep_data)
plt.title('Boxplot du nombre de tokens des descriptions par catégorie')
plt.xlabel('Catégorie')
plt.xticks(rotation=45)
plt.ylabel('Nombre de tokens')
plt.show()
No description has been provided for this image
In [16]:
# Calculer la moyenne et la médiane pour chaque catégorie
mean_median_data = prep_data.groupby('categ_0')['token_count'].agg(['mean', 'median', 'max', 'min']).reset_index()
mean_median_data
Out[16]:
categ_0 mean median max min
0 baby care 78.086667 58.0 411 13
1 beauty and personal care 56.940000 31.0 570 18
2 computers 84.860000 33.0 572 20
3 home decor & festive needs 85.160000 39.0 394 16
4 home furnishing 57.473333 24.0 389 18
5 kitchen & dining 99.793333 75.5 355 14
6 watches 47.966667 43.5 276 27
  • après une tokenisation des descriptions faite avec le RegexpTokenizer de nltk, on observe qu'une bonne partie de nos textes sont plus longs que ceux ayant servis à l'entraînement de CLIP
  • Le modèle CLIP (Contrastive Language-Image Pretraining) a été entraîné par OpenAI sur un vaste ensemble de données appelé WebImageText (WIT).
  • En effet, le modèle CLIP a été pré-entraîné avec une longueur de contexte spécifique (77 tokens), et changer cette longueur peut affecter les performances du modèle.
  • normalement il n'est pas nécessaire de tokeniser les textes avant de les envoyer à CLIP, car il a son propre tokenisateur.
  • nous allons néanmoins essayer de maximiser la qualité de l'information envoyée, en réduisant les mots moins utiles, nous verrons si cela améliore les performancesde CLIP.
  • nous allons donc tester 2 approches :
    1. en lui envoyant les textes tokenisés avec le RegexpTokenizer de nltk pour supprimer un maximum de mots peu utiles, puis tronquer les textes à 77 tokens en utilisant la tokenisation de CLIP.
    2. en lui envoyant les textes non tokenisés et juste tronquer les textes à 77 tokens en utilisant la tokenisation de CLIP.
In [17]:
tokenizer = RegexpTokenizer(r'\b\w*[a-zA-Z]+\w*\b|\b[a-zA-Z]+\b')


# Fonction pour compter le nombre de tokens dans une description
def len_text(text):
    return len(text)

# Fonction pour compter le nombre de tokens dans une description
def count_tokens(text):
    tokens = tokenizer.tokenize(text)
    return len(tokens)

# Fonction pour l'approche 1 : Tokeniser avec NLTK, puis tronquer avec CLIP
def approach_nltk(text):
    # Tokeniser avec NLTK
    tokens = tokenizer.tokenize(text)
    #truncated_tokens = tokens[:max_length]
    token_string = ' '.join(tokens)

    return token_string
In [18]:
prep_data['len_text'] = prep_data['description'].apply(len_text)
prep_data['token_nltk'] = prep_data['description'].apply(approach_nltk)
prep_data['token_nltk_len'] = prep_data['token_nltk'].apply(len_text)
prep_data['token_nltk_count'] = prep_data['token_nltk'].apply(count_tokens)

prep_data.head(2)
Out[18]:
uniq_id product_name description product_category_tree image categ_0 sub_categories label token_count len_text token_nltk token_nltk_len token_nltk_count
0 55b85ea15a1536d46b7190ad6fff8ce7 Elegance Polyester Multicolor Abstract Eyelet ... Key Features of Elegance Polyester Multicolor ... ["Home Furnishing >> Curtains & Accessories >>... 55b85ea15a1536d46b7190ad6fff8ce7.jpg home furnishing Curtains & Accessories Curtains Elegance Polye... 4 226 1420 Key Features of Elegance Polyester Multicolor ... 1373 226
1 7b72c92c2f6c40268628ec5f14c6d590 Sathiyas Cotton Bath Towel Specifications of Sathiyas Cotton Bath Towel (... ["Baby Care >> Baby Bath & Skin >> Baby Bath T... 7b72c92c2f6c40268628ec5f14c6d590.jpg baby care Baby Bath & Skin Baby Bath Towels Sathiyas Bab... 0 68 444 Specifications of Sathiyas Cotton Bath Towel B... 418 68
In [19]:
token_nltk_count = prep_data.groupby('categ_0')['token_nltk_count'].agg(['mean', 'median', 'max', 'min']).reset_index()
token_nltk_count
Out[19]:
categ_0 mean median max min
0 baby care 78.086667 58.0 411 13
1 beauty and personal care 56.940000 31.0 570 18
2 computers 84.860000 33.0 572 20
3 home decor & festive needs 85.160000 39.0 394 16
4 home furnishing 57.473333 24.0 389 18
5 kitchen & dining 99.793333 75.5 355 14
6 watches 47.966667 43.5 276 27
In [20]:
text_truncated_count = prep_data.groupby('categ_0')['token_count'].agg(['mean', 'median', 'max', 'min']).reset_index()
text_truncated_count
Out[20]:
categ_0 mean median max min
0 baby care 78.086667 58.0 411 13
1 beauty and personal care 56.940000 31.0 570 18
2 computers 84.860000 33.0 572 20
3 home decor & festive needs 85.160000 39.0 394 16
4 home furnishing 57.473333 24.0 389 18
5 kitchen & dining 99.793333 75.5 355 14
6 watches 47.966667 43.5 276 27

Échantillons de descriptions tronquées par catégories

In [21]:
random_samples = prep_data.groupby('categ_0').apply(lambda x: x.sample(1, random_state=seed_value)).reset_index(drop=True)
for index, row in random_samples.iterrows():
    print(f" Exemple de description pour la catégorie ** {row['categ_0']} ** \n Longueur token_nltk : {len(row['token_nltk'])} \n {row['token_nltk']} \n")
 Exemple de description pour la catégorie ** baby care ** 
 Longueur token_nltk : 266 
 Key Features of cherry crumble california Baby Boy s Dungaree Fabric Cotton Brand Color Grey Olive Camouflage Specifications of cherry crumble california Baby Boy s Dungaree Top Details Fabric Cotton Type Dungaree General Details Pattern Printed Ideal For Baby Boy s 

 Exemple de description pour la catégorie ** beauty and personal care ** 
 Longueur token_nltk : 973 
 Vincent Valentine Paris Set of Dark Fire Dark Fire Majesty Deodorants Combo Set Set of Price Rs Dark Fire sparkles with an enchanting top note blend of Black Currant and Star Anise The distinctive spiciness is embraced by Galanga Root for depth and Green Pepper extract for warmth The base is rich and woody with Balsam Cedar entwined with Vanilla Beans Passionate and royal majesty the latest beautiful perfume from Anna Andre distinguishes itself from all others It pampers the young and extravagant woman with a neo classical touch Dark Fire sparkles with an enchanting top note blend of Black Currant and Star Anise The distinctive spiciness is embraced by Galanga Root for depth and Green Pepper extract for warmth The base is rich and woody with Balsam Cedar entwined with Vanilla Beans Passionate and royal majesty the latest beautiful perfume from Anna Andre distinguishes itself from all others It pampers the young and extravagant woman with a neo classical touch 

 Exemple de description pour la catégorie ** computers ** 
 Longueur token_nltk : 129 
 Buy Binatone WR3000N only for Rs from Flipkart com Only Genuine Products Day Replacement Guarantee Free Shipping Cash On Delivery 

 Exemple de description pour la catégorie ** home decor & festive needs ** 
 Longueur token_nltk : 182 
 Buy Rastogi Handicrafts Showpiece cm for Rs online Rastogi Handicrafts Showpiece cm at best prices with FREE shipping cash on delivery Only Genuine Products Day Replacement Guarantee 

 Exemple de description pour la catégorie ** home furnishing ** 
 Longueur token_nltk : 183 
 Specifications of JewelKraft Designs Brown Pink Table Linen Set General Brand JewelKraft Designs Design Code MN Style Code Color Brown Pink In the Box Sales Package table mats napkins 

 Exemple de description pour la catégorie ** kitchen & dining ** 
 Longueur token_nltk : 188 
 Buy Rajesh Digital BEST DAD Ceramic Mug for Rs online Rajesh Digital BEST DAD Ceramic Mug at best prices with FREE shipping cash on delivery Only Genuine Products Day Replacement Guarantee 

 Exemple de description pour la catégorie ** watches ** 
 Longueur token_nltk : 211 
 Disney Analog Watch For Boys Girls Buy Disney Analog Watch For Boys Girls Online at Rs in India Only at Flipkart com Great Discounts Only Genuine Products Day Replacement Guarantee Free Shipping Cash On Delivery 

/tmp/ipykernel_911805/2132760375.py:1: DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.
  random_samples = prep_data.groupby('categ_0').apply(lambda x: x.sample(1, random_state=seed_value)).reset_index(drop=True)

Fréquences des tokens uniques par catégories

In [22]:
# fréquence des tokens uniques dans les descriptions des articles par catégorie principale
token_frequencies = {}

for _, row in prep_data.iterrows():
    categ_0 = row['categ_0']
    description = row['description']
    
    tokens = tokenizer.tokenize(description)
    if categ_0 not in token_frequencies:
        token_frequencies[categ_0] = {}
    
    for token in tokens:
        if token not in token_frequencies[categ_0]:
            token_frequencies[categ_0][token] = 0
        token_frequencies[categ_0][token] += 1

freq_data = []
for categ_0, tokens in token_frequencies.items():
    for token, freq in tokens.items():
        freq_data.append({'categ_0': categ_0, 'token': token, 'frequency': freq})

descript_freq_df = pd.DataFrame(freq_data)
descript_freq_df.rename(columns={'token': 'descript_tokens'}, inplace=True)
descript_freq_df
Out[22]:
categ_0 descript_tokens frequency
0 home furnishing Key 32
1 home furnishing Features 52
2 home furnishing of 296
3 home furnishing Elegance 4
4 home furnishing Polyester 56
... ... ... ...
11052 computers me 4
11053 computers looking 4
11054 computers upwards 4
11055 computers Red 4
11056 computers bull 4

11057 rows × 3 columns

In [23]:
for categ_0 in descript_freq_df['categ_0'].unique():
    # Filtrer les tokens pour la catégorie principale actuelle
    tokens = descript_freq_df[descript_freq_df['categ_0'] == categ_0]
    
    # Créer un dictionnaire de fréquences pour WordCloud
    token_dict = dict(zip(tokens['descript_tokens'], tokens['frequency']))
    
    # Générer le nuage de mots
    wordcloud = WordCloud(width=1200, height=400, background_color='white').generate_from_frequencies(token_dict)
    
    # Afficher le nuage de mots
    plt.figure(figsize=(20, 5))
    plt.imshow(wordcloud, interpolation='bilinear')
    plt.title(f'Nuage de mots dans les descriptions des articles pour la catégorie principale: {categ_0}')
    plt.axis('off')
    plt.show()
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image

Les images¶

In [24]:
# récupérer les chemins vers les fichiers images
path_images = "./Flipkart/Images/"
prep_data['image_path'] = path_images + prep_data['image']
# obtenir les dimensions des images d'origines
prep_data['height_origin'], prep_data['width_origin'] = zip(*prep_data['image_path'].apply(get_image_dimensions))
prep_data.head(2)
[ WARN:0@624.644] global loadsave.cpp:248 findDecoder imread_('./Flipkart/Images/41384da51732c0b4df3de8f395714fbb.jpg'): can't open/read file: check file path/integrity
[ WARN:0@624.730] global loadsave.cpp:248 findDecoder imread_('./Flipkart/Images/b52073e7ed9c00c4108cae4eb0c49c1a.jpg'): can't open/read file: check file path/integrity
[ WARN:0@624.847] global loadsave.cpp:248 findDecoder imread_('./Flipkart/Images/2d50e4c6ccf8befe9335ac8f97a11712.jpg'): can't open/read file: check file path/integrity
[ WARN:0@625.437] global loadsave.cpp:248 findDecoder imread_('./Flipkart/Images/46e6853da6b0c796b7a0d8203ceaa88e.jpg'): can't open/read file: check file path/integrity
[ WARN:0@627.359] global loadsave.cpp:248 findDecoder imread_('./Flipkart/Images/9833d0de7f7e1927c807411c10b19189.jpg'): can't open/read file: check file path/integrity
[ WARN:0@627.619] global loadsave.cpp:248 findDecoder imread_('./Flipkart/Images/4d2e9f36823bad0f6fe8c6b19bb92bdb.jpg'): can't open/read file: check file path/integrity
Out[24]:
uniq_id product_name description product_category_tree image categ_0 sub_categories label token_count len_text token_nltk token_nltk_len token_nltk_count image_path height_origin width_origin
0 55b85ea15a1536d46b7190ad6fff8ce7 Elegance Polyester Multicolor Abstract Eyelet ... Key Features of Elegance Polyester Multicolor ... ["Home Furnishing >> Curtains & Accessories >>... 55b85ea15a1536d46b7190ad6fff8ce7.jpg home furnishing Curtains & Accessories Curtains Elegance Polye... 4 226 1420 Key Features of Elegance Polyester Multicolor ... 1373 226 ./Flipkart/Images/55b85ea15a1536d46b7190ad6fff... 3600.0 3600.0
1 7b72c92c2f6c40268628ec5f14c6d590 Sathiyas Cotton Bath Towel Specifications of Sathiyas Cotton Bath Towel (... ["Baby Care >> Baby Bath & Skin >> Baby Bath T... 7b72c92c2f6c40268628ec5f14c6d590.jpg baby care Baby Bath & Skin Baby Bath Towels Sathiyas Bab... 0 68 444 Specifications of Sathiyas Cotton Bath Towel B... 418 68 ./Flipkart/Images/7b72c92c2f6c40268628ec5f14c6... 1293.0 2388.0

Taille des images

In [25]:
# box plot pour les hauteurs des images par catégorie
plt.figure(figsize=(15, 6))
sns.boxplot(x='categ_0', y='height_origin', data=prep_data)
plt.title('Distribution des hauteurs des images par catégorie')
plt.xlabel('Catégorie')
plt.ylabel('Hauteur de l\'image')
plt.show()

# box plot pour les largeurs des images par catégorie
plt.figure(figsize=(15, 6))
sns.boxplot(x='categ_0', y='width_origin', data=prep_data)
plt.title('Distribution des largeurs des images par catégorie')
plt.xlabel('Catégorie')
plt.ylabel('Largeur de l\'image')
plt.show()
No description has been provided for this image
No description has been provided for this image
  • les dimensions des images ne sont pas uniformes, même au sein de chaque catégorie (en particulier pour la catégorie kitchen&dining)
  • il faudra prévoir dans le processus de prétraitement des images un redimensionnement pour normer les tailles des images, car les CNN notamment nécessitent d'avoir des données en entrée de même dimensions
In [26]:
# Initialiser la colonne 'processed_image' avec des valeurs None
prep_data['reshaped_image_path'] = None

# Créer un répertoire pour stocker les images traitées
output_dir = './reshaped_images'
os.makedirs(output_dir, exist_ok=True)
In [27]:
# Fonction pour obtenir des images carrées, avec la dimension la plus petite compléter avec des pixels blancs
def pad_image_to_square(image):
    h, w = image.shape[:2]
    if h > w:
        pad = h - w
        padded_image = cv2.copyMakeBorder(image, 0, 0, pad // 2, pad - pad // 2, cv2.BORDER_CONSTANT, value=[255, 255, 255])
    elif w > h:
        pad = w - h
        padded_image = cv2.copyMakeBorder(image, pad // 2, pad - pad // 2, 0, 0, cv2.BORDER_CONSTANT, value=[255, 255, 255])
    else:
        padded_image = image
    return padded_image

# Traiter les images, les sauvegarder et mettre à jour le chemin des images traitées dans le DataFrame
for index, row in prep_data.iterrows():
    image_path = row['image_path']
    img = cv2.imread(image_path)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    padded_img = pad_image_to_square(img)
    output_path = os.path.join(output_dir, os.path.basename(image_path))
    cv2.imwrite(output_path, cv2.cvtColor(padded_img, cv2.COLOR_RGB2BGR))
    prep_data.at[index, 'reshaped_image_path'] = output_path

# Afficher un échantillon de 6 images aléatoires dans chaque catégorie après le traitement
categories = prep_data['categ_0'].unique()
fig, axes = plt.subplots(len(categories), 6, figsize=(18, len(categories) * 3), facecolor='black')

for i, category in enumerate(categories):
    category_images = prep_data[prep_data['categ_0'] == category]['reshaped_image_path']
    sampled_images = random.sample(list(category_images), min(6, len(category_images)))
    
    for j, image_path in enumerate(sampled_images):
        img = cv2.imread(image_path)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        ax = axes[i, j] if len(categories) > 1 else axes[j]
        ax.imshow(img)
        ax.set_title(f'{category}', color='white')
        ax.axis('off')

plt.tight_layout()
plt.show()
No description has been provided for this image
In [28]:
# Ajouter les dimensions des images mises au carré pour vérification
prep_data['reshaped_height'], prep_data['reshaped_width'] = zip(*prep_data['reshaped_image_path'].apply(get_image_dimensions))
prep_data.head(3)
Out[28]:
uniq_id product_name description product_category_tree image categ_0 sub_categories label token_count len_text token_nltk token_nltk_len token_nltk_count image_path height_origin width_origin reshaped_image_path reshaped_height reshaped_width
0 55b85ea15a1536d46b7190ad6fff8ce7 Elegance Polyester Multicolor Abstract Eyelet ... Key Features of Elegance Polyester Multicolor ... ["Home Furnishing >> Curtains & Accessories >>... 55b85ea15a1536d46b7190ad6fff8ce7.jpg home furnishing Curtains & Accessories Curtains Elegance Polye... 4 226 1420 Key Features of Elegance Polyester Multicolor ... 1373 226 ./Flipkart/Images/55b85ea15a1536d46b7190ad6fff... 3600.0 3600.0 ./reshaped_images/55b85ea15a1536d46b7190ad6fff... 3600 3600
1 7b72c92c2f6c40268628ec5f14c6d590 Sathiyas Cotton Bath Towel Specifications of Sathiyas Cotton Bath Towel (... ["Baby Care >> Baby Bath & Skin >> Baby Bath T... 7b72c92c2f6c40268628ec5f14c6d590.jpg baby care Baby Bath & Skin Baby Bath Towels Sathiyas Bab... 0 68 444 Specifications of Sathiyas Cotton Bath Towel B... 418 68 ./Flipkart/Images/7b72c92c2f6c40268628ec5f14c6... 1293.0 2388.0 ./reshaped_images/7b72c92c2f6c40268628ec5f14c6... 2388 2388
2 64d5d4a258243731dc7bbb1eef49ad74 Eurospa Cotton Terry Face Towel Set Key Features of Eurospa Cotton Terry Face Towe... ["Baby Care >> Baby Bath & Skin >> Baby Bath T... 64d5d4a258243731dc7bbb1eef49ad74.jpg baby care Baby Bath & Skin Baby Bath Towels Eurospa Baby... 0 199 1258 Key Features of Eurospa Cotton Terry Face Towe... 1167 199 ./Flipkart/Images/64d5d4a258243731dc7bbb1eef49... 729.0 982.0 ./reshaped_images/64d5d4a258243731dc7bbb1eef49... 982 982

Dataset final¶

In [29]:
# sélection du dataset préparé pour l'approche CLIP
data_final = prep_data.filter(['uniq_id', 'product_name', 'description', 'token_nltk', 'categ_0', 'label', 'reshaped_image_path'])
data_final.head(2)
Out[29]:
uniq_id product_name description token_nltk categ_0 label reshaped_image_path
0 55b85ea15a1536d46b7190ad6fff8ce7 Elegance Polyester Multicolor Abstract Eyelet ... Key Features of Elegance Polyester Multicolor ... Key Features of Elegance Polyester Multicolor ... home furnishing 4 ./reshaped_images/55b85ea15a1536d46b7190ad6fff...
1 7b72c92c2f6c40268628ec5f14c6d590 Sathiyas Cotton Bath Towel Specifications of Sathiyas Cotton Bath Towel (... Specifications of Sathiyas Cotton Bath Towel B... baby care 0 ./reshaped_images/7b72c92c2f6c40268628ec5f14c6...

Enregistrer le DataFrame préparé pour l'approche CLIP dans un fichier CSV¶

csv_file_path = 'clip_dataset.csv' data_final.to_csv(csv_file_path, index=False)

print(f"Le DataFrame a été enregistré dans le fichier {csv_file_path}")

BASELINE - Classification d'images avec DenseNet121¶

  • meilleur modèle retenue pour la classification par image automatique des produits mis en ligne : DenseNet121, pré-entraîné AVEC poids imagenet & SANS data-augmentation.

Liste des résultats des scénarii¶

In [30]:
# enregistrer les résultats sur le test pour comparaison des scénarii
perf_test_df = pd.DataFrame(columns=['Scenario', 'Description', 'Accuracy_Train', 'Accuracy_Test', 'Durée_totale_computation'])

Fonctions¶

In [31]:
# Fonction pour charger et prétraiter les images pour les adapter au modèle DenseNet121
def load_and_preprocess_image(path, label):
    image = tf.io.read_file(path)
    image = tf.image.decode_jpeg(image, channels=3)
    image = tf.image.resize(image, [img_height, img_width])
    image = image / 255.0  # Normaliser les pixels entre 0 et 1
    return image, label

# Créer des datasets adaptés à TensorFlow pour chaque ensemble
def create_dataset(paths, labels, batch_size=32):
    dataset = tf.data.Dataset.from_tensor_slices((paths, labels))
    dataset = dataset.map(load_and_preprocess_image, num_parallel_calls=tf.data.experimental.AUTOTUNE)
    dataset = dataset.shuffle(buffer_size=len(paths), seed=seed_value)
    dataset = dataset.batch(batch_size)
    dataset = dataset.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)
    return dataset

# extraire les labels des dataset densenet
def extract_labels(dataset):
    labels = []
    for _, label in dataset.unbatch():
        labels.append(label.numpy())
    return np.array(labels)

# graphique matrice de confusion avec validation pour denseNet
def plot_confusion_matrix(conf_matrix, dataset_name, data_augment=False):
    if dataset_name == 'VALIDATION':
        color = 'Greens'
    elif dataset_name == 'TRAIN':
        color = 'Blues'
    elif dataset_name == 'TRAIN+VALIDATION':
        color = 'PuBuGn' 
    elif dataset_name == 'TEST':
        color = 'YlOrBr' # Oranges YlOrBr
    plt.figure(figsize=(10, 8))
    sns.heatmap(conf_matrix, annot=True, fmt='d', cmap=color, xticklabels=label_to_category.values(), yticklabels=label_to_category.values())
    plt.xlabel('Prédits', fontsize=14)
    plt.ylabel('Réels', fontsize=14)
    if data_augment:
        plt.title(f'Confusion Matrix - {dataset_name} - avec data augmentation', fontsize=16)
    else:
        plt.title(f'Confusion Matrix - {dataset_name} - sans data augmentation', fontsize=16)
    plt.show()
    
# visualisation des images bien et mal classées sur le TEST
def visualisation_images_TEST(etat, y_test, y_test_pred_classes, X_test, dict_label=label_to_category, num_examples=6):
    categories = np.unique(y_test)

    # Récupérer les index des images bien et mal classées
    if etat == 'BIEN':
        indices = np.where(y_test_pred_classes == y_test)[0]
        title = "TEST - Images BIEN classées"
    elif etat == 'MAL':
        indices = np.where(y_test_pred_classes != y_test)[0]
        title = "TEST - Images MAL classées"
    else:
        raise ValueError("L'état doit être 'BIEN' ou 'MAL'")

    # Init dict des exemples
    examples = {category: [] for category in categories}
    # Récupérer les exemples par catégories
    for category in categories:
        category_indices = indices[y_test[indices] == category]
        if len(category_indices) >= num_examples:
            examples[category] = category_indices[:num_examples]
        else:
            examples[category] = category_indices

    # Affichage des exemples par catégories
    fig, axes = plt.subplots(len(categories), num_examples, figsize=(num_examples * 3, len(categories) * 3), facecolor='black')
    fig.suptitle(title, color='white', fontsize=16)

    plt.subplots_adjust(hspace=0.5)

    for i, category in enumerate(categories):
        axes[i, 0].annotate(f'Catégorie réelle : {label_to_category[category]}', xy=(0, 1), xytext=(0, 1.2),
                            xycoords='axes fraction', textcoords='axes fraction',
                            ha='left', va='bottom', color='white', fontsize=14, annotation_clip=False)

        for j in range(num_examples):
            if j < len(examples[category]):
                idx = examples[category][j]
                rescaled_image = X_test[idx]  # Les images sont déjà normalisées
                axes[i, j].imshow(rescaled_image)
                pred_label = label_to_category[y_test_pred_classes[idx]]
                axes[i, j].set_title(f"Pred: {pred_label}", color='white', fontsize=10)
            axes[i, j].axis('off')

    plt.show()
    
# Fonction pour obtenir les prédictions du modèle sur un dataset
def get_predictions(model, dataset):
    y_true = []
    y_pred = []
    X_true = []

    for images, labels in dataset:
        y_true.extend(labels.numpy())
        preds = model.predict(images)
        y_pred.extend(np.argmax(preds, axis=1))
        X_true.extend(images.numpy())

    return np.array(X_true), np.array(y_true), np.array(y_pred)

    
In [32]:
# adapter les dimensions des images pour le modèle DenseNet121
img_height = 224
img_width = 224
In [33]:
# récupérer les chemins des images et leurs labels
image_paths = data_final['reshaped_image_path'].values
labels = data_final['label'].values 
In [34]:
# shuffle des index des images pour mélanger les données avant la séparation en ensemble de train et de test
indices = np.arange(len(image_paths))
np.random.shuffle(indices)
image_paths = image_paths[indices]
labels = labels[indices]

Train-Test Split¶

In [35]:
# répartition en 70% / 15% / 15%
train_paths, temp_paths, train_labels, temp_labels = train_test_split(
    image_paths, labels, test_size=0.30, stratify=labels, random_state=seed_value)

val_paths, test_paths, val_labels, test_labels = train_test_split(
    temp_paths, temp_labels, test_size=0.50, stratify=temp_labels, random_state=seed_value)
In [36]:
# création des datasets
train_dataset = create_dataset(train_paths, train_labels)
val_dataset = create_dataset(val_paths, val_labels)
test_dataset = create_dataset(test_paths, test_labels)
print("nbre de batch dans train_dataset", len(train_dataset))
print("nbre de batch dans val_dataset", len(val_dataset))
print("nbre de batch dans test_dataset", len(test_dataset))
nbre de batch dans train_dataset 23
nbre de batch dans val_dataset 5
nbre de batch dans test_dataset 5
In [37]:
# s'assurer de la répartition équilibrée des classes dans les ensembles d'entraînement, de validation et de test

# labels des datasets
train_labels = extract_labels(train_dataset)
val_labels = extract_labels(val_dataset)
test_labels = extract_labels(test_dataset)

# répartition des classes
train_counts = np.unique(train_labels, return_counts=True)
val_counts = np.unique(val_labels, return_counts=True)
test_counts = np.unique(test_labels, return_counts=True)
total_counts = np.sum([train_counts[1], val_counts[1], test_counts[1]])

train_total_percentage = (np.sum(train_counts[1]) / total_counts) * 100
val_total_percentage = (np.sum(val_counts[1]) / total_counts) * 100
test_total_percentage = (np.sum(test_counts[1]) / total_counts) * 100

train_percentages = (train_counts[1] / total_counts) * 100
val_percentages = (val_counts[1] / total_counts) * 100
test_percentages = (test_counts[1] / total_counts) * 100

# correspondance avec les noms des catégories
categories = np.concatenate([train_counts[0], val_counts[0], test_counts[0]])
category_names = [f'{label} - {label_to_category[label]}' for label in categories]

data = {
    'Catégories': category_names,
    'Pourcentage': np.concatenate([train_percentages, val_percentages, test_percentages]),
    'Ensemble': ['Train'] * len(train_counts[0]) + ['Validation'] * len(val_counts[0]) + ['Test'] * len(test_counts[0])
}
df = pd.DataFrame(data)

palette = {'Train': '#1f77b4', 'Validation': '#2ca02c', 'Test': '#ff7f0e'}
plt.figure(figsize=(15, 8))
sns.barplot(x='Catégories', y='Pourcentage', hue='Ensemble', data=df, palette=palette)
plt.title('Répartition des classes dans les ensembles d\'entraînement, de validation et de test')
plt.xlabel('Catégories')
plt.ylabel('Pourcentage du dataset total')
plt.xticks(rotation=45)
handles, labels = plt.gca().get_legend_handles_labels()
labels = [
    f'Train - {train_total_percentage:.2f}%',
    f'Validation - {val_total_percentage:.2f}%',
    f'Test - {test_total_percentage:.2f}%'
]
plt.legend(handles=handles, labels=labels, title='Sous-ensembles totaux')
plt.show()
2025-01-22 14:51:36.839751: W tensorflow/core/framework/local_rendezvous.cc:404] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence
2025-01-22 14:51:37.498145: W tensorflow/core/framework/local_rendezvous.cc:404] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence
2025-01-22 14:51:38.320979: W tensorflow/core/framework/local_rendezvous.cc:404] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence
No description has been provided for this image
In [38]:
label_to_category
Out[38]:
{0: 'baby care',
 1: 'beauty and personal care',
 2: 'computers',
 3: 'home decor & festive needs',
 4: 'home furnishing',
 5: 'kitchen & dining',
 6: 'watches'}

Vérifier la reproductibilité¶

In [39]:
tf.random.set_seed(seed_value)
tf.keras.utils.set_random_seed(seed_value) 
random_values_1 = tf.random.uniform([5], seed=seed_value)
print("TF/KERAS Valeurs aléatoires 1:", random_values_1.numpy())
tf.random.set_seed(seed_value)
tf.keras.utils.set_random_seed(seed_value) 
random_values_2 = tf.random.uniform([5], seed=seed_value)
print("TF/KERAS Valeurs aléatoires 2:", random_values_2.numpy())
assert np.array_equal(random_values_1.numpy(), random_values_2.numpy()), "TF/KERAS Les valeurs aléatoires ne sont pas identiques"
print("TF/KERAS Les valeurs aléatoires sont identiques, la graine est correctement fixée.")
TF/KERAS Valeurs aléatoires 1: [0.43668258 0.59952414 0.27555966 0.6870636  0.05337238]
TF/KERAS Valeurs aléatoires 2: [0.43668258 0.59952414 0.27555966 0.6870636  0.05337238]
TF/KERAS Les valeurs aléatoires sont identiques, la graine est correctement fixée.

Liste des GPU¶

In [40]:
tf.config.list_physical_devices('GPU')
Out[40]:
[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU'),
 PhysicalDevice(name='/physical_device:GPU:1', device_type='GPU'),
 PhysicalDevice(name='/physical_device:GPU:2', device_type='GPU'),
 PhysicalDevice(name='/physical_device:GPU:3', device_type='GPU')]

Entraînement DenseNet121¶

  • pré-entraînée AVEC les poids imagenet - SANS Data_augmentation

Modèle¶

In [41]:
# couche d'entrée
input_tensor = tf.keras.layers.Input(shape=(img_height, img_width, 3))
# Desnet121 pré-entraîné sur ImageNet sans la couche de sortie initiale
base_model = DenseNet121(weights='imagenet', include_top=False, input_tensor=input_tensor)
# Geler les poids des couches du modèle de base (=transfert learning = préserve les connaissances issues des poids du modèle pré-entraîné)
for layer in base_model.layers:
    layer.trainable = False
    
# couches de sorties personnalisées
x = base_model.output
x = tf.keras.layers.Flatten()(x)
x = tf.keras.layers.Dense(1024, activation='relu')(x)
x = tf.keras.layers.Dropout(0.5)(x)
output_tensor = tf.keras.layers.Dense(7, activation='softmax')(x)  # 7 classes

model = tf.keras.models.Model(inputs=input_tensor, outputs=output_tensor)

# paramètres d'entraînement
nb_epochs=25
es_patience=8
lr_patience=3
# visualisation du modèle
model.summary()
Model: "functional"
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃ Layer (type)        ┃ Output Shape      ┃    Param # ┃ Connected to      ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ input_layer         │ (None, 224, 224,  │          0 │ -                 │
│ (InputLayer)        │ 3)                │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ zero_padding2d      │ (None, 230, 230,  │          0 │ input_layer[0][0] │
│ (ZeroPadding2D)     │ 3)                │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv1_conv (Conv2D) │ (None, 112, 112,  │      9,408 │ zero_padding2d[0… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv1_bn            │ (None, 112, 112,  │        256 │ conv1_conv[0][0]  │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv1_relu          │ (None, 112, 112,  │          0 │ conv1_bn[0][0]    │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ zero_padding2d_1    │ (None, 114, 114,  │          0 │ conv1_relu[0][0]  │
│ (ZeroPadding2D)     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ pool1               │ (None, 56, 56,    │          0 │ zero_padding2d_1… │
│ (MaxPooling2D)      │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_0_bn   │ (None, 56, 56,    │        256 │ pool1[0][0]       │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_0_relu │ (None, 56, 56,    │          0 │ conv2_block1_0_b… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_1_conv │ (None, 56, 56,    │      8,192 │ conv2_block1_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_1_bn   │ (None, 56, 56,    │        512 │ conv2_block1_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_1_relu │ (None, 56, 56,    │          0 │ conv2_block1_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_2_conv │ (None, 56, 56,    │     36,864 │ conv2_block1_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_concat │ (None, 56, 56,    │          0 │ pool1[0][0],      │
│ (Concatenate)       │ 96)               │            │ conv2_block1_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block2_0_bn   │ (None, 56, 56,    │        384 │ conv2_block1_con… │
│ (BatchNormalizatio… │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block2_0_relu │ (None, 56, 56,    │          0 │ conv2_block2_0_b… │
│ (Activation)        │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block2_1_conv │ (None, 56, 56,    │     12,288 │ conv2_block2_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block2_1_bn   │ (None, 56, 56,    │        512 │ conv2_block2_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block2_1_relu │ (None, 56, 56,    │          0 │ conv2_block2_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block2_2_conv │ (None, 56, 56,    │     36,864 │ conv2_block2_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block2_concat │ (None, 56, 56,    │          0 │ conv2_block1_con… │
│ (Concatenate)       │ 128)              │            │ conv2_block2_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block3_0_bn   │ (None, 56, 56,    │        512 │ conv2_block2_con… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block3_0_relu │ (None, 56, 56,    │          0 │ conv2_block3_0_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block3_1_conv │ (None, 56, 56,    │     16,384 │ conv2_block3_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block3_1_bn   │ (None, 56, 56,    │        512 │ conv2_block3_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block3_1_relu │ (None, 56, 56,    │          0 │ conv2_block3_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block3_2_conv │ (None, 56, 56,    │     36,864 │ conv2_block3_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block3_concat │ (None, 56, 56,    │          0 │ conv2_block2_con… │
│ (Concatenate)       │ 160)              │            │ conv2_block3_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block4_0_bn   │ (None, 56, 56,    │        640 │ conv2_block3_con… │
│ (BatchNormalizatio… │ 160)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block4_0_relu │ (None, 56, 56,    │          0 │ conv2_block4_0_b… │
│ (Activation)        │ 160)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block4_1_conv │ (None, 56, 56,    │     20,480 │ conv2_block4_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block4_1_bn   │ (None, 56, 56,    │        512 │ conv2_block4_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block4_1_relu │ (None, 56, 56,    │          0 │ conv2_block4_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block4_2_conv │ (None, 56, 56,    │     36,864 │ conv2_block4_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block4_concat │ (None, 56, 56,    │          0 │ conv2_block3_con… │
│ (Concatenate)       │ 192)              │            │ conv2_block4_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block5_0_bn   │ (None, 56, 56,    │        768 │ conv2_block4_con… │
│ (BatchNormalizatio… │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block5_0_relu │ (None, 56, 56,    │          0 │ conv2_block5_0_b… │
│ (Activation)        │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block5_1_conv │ (None, 56, 56,    │     24,576 │ conv2_block5_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block5_1_bn   │ (None, 56, 56,    │        512 │ conv2_block5_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block5_1_relu │ (None, 56, 56,    │          0 │ conv2_block5_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block5_2_conv │ (None, 56, 56,    │     36,864 │ conv2_block5_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block5_concat │ (None, 56, 56,    │          0 │ conv2_block4_con… │
│ (Concatenate)       │ 224)              │            │ conv2_block5_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block6_0_bn   │ (None, 56, 56,    │        896 │ conv2_block5_con… │
│ (BatchNormalizatio… │ 224)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block6_0_relu │ (None, 56, 56,    │          0 │ conv2_block6_0_b… │
│ (Activation)        │ 224)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block6_1_conv │ (None, 56, 56,    │     28,672 │ conv2_block6_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block6_1_bn   │ (None, 56, 56,    │        512 │ conv2_block6_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block6_1_relu │ (None, 56, 56,    │          0 │ conv2_block6_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block6_2_conv │ (None, 56, 56,    │     36,864 │ conv2_block6_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block6_concat │ (None, 56, 56,    │          0 │ conv2_block5_con… │
│ (Concatenate)       │ 256)              │            │ conv2_block6_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ pool2_bn            │ (None, 56, 56,    │      1,024 │ conv2_block6_con… │
│ (BatchNormalizatio… │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ pool2_relu          │ (None, 56, 56,    │          0 │ pool2_bn[0][0]    │
│ (Activation)        │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ pool2_conv (Conv2D) │ (None, 56, 56,    │     32,768 │ pool2_relu[0][0]  │
│                     │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ pool2_pool          │ (None, 28, 28,    │          0 │ pool2_conv[0][0]  │
│ (AveragePooling2D)  │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_0_bn   │ (None, 28, 28,    │        512 │ pool2_pool[0][0]  │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_0_relu │ (None, 28, 28,    │          0 │ conv3_block1_0_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_1_conv │ (None, 28, 28,    │     16,384 │ conv3_block1_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_1_bn   │ (None, 28, 28,    │        512 │ conv3_block1_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_1_relu │ (None, 28, 28,    │          0 │ conv3_block1_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_2_conv │ (None, 28, 28,    │     36,864 │ conv3_block1_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_concat │ (None, 28, 28,    │          0 │ pool2_pool[0][0], │
│ (Concatenate)       │ 160)              │            │ conv3_block1_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block2_0_bn   │ (None, 28, 28,    │        640 │ conv3_block1_con… │
│ (BatchNormalizatio… │ 160)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block2_0_relu │ (None, 28, 28,    │          0 │ conv3_block2_0_b… │
│ (Activation)        │ 160)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block2_1_conv │ (None, 28, 28,    │     20,480 │ conv3_block2_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block2_1_bn   │ (None, 28, 28,    │        512 │ conv3_block2_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block2_1_relu │ (None, 28, 28,    │          0 │ conv3_block2_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block2_2_conv │ (None, 28, 28,    │     36,864 │ conv3_block2_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block2_concat │ (None, 28, 28,    │          0 │ conv3_block1_con… │
│ (Concatenate)       │ 192)              │            │ conv3_block2_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block3_0_bn   │ (None, 28, 28,    │        768 │ conv3_block2_con… │
│ (BatchNormalizatio… │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block3_0_relu │ (None, 28, 28,    │          0 │ conv3_block3_0_b… │
│ (Activation)        │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block3_1_conv │ (None, 28, 28,    │     24,576 │ conv3_block3_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block3_1_bn   │ (None, 28, 28,    │        512 │ conv3_block3_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block3_1_relu │ (None, 28, 28,    │          0 │ conv3_block3_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block3_2_conv │ (None, 28, 28,    │     36,864 │ conv3_block3_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block3_concat │ (None, 28, 28,    │          0 │ conv3_block2_con… │
│ (Concatenate)       │ 224)              │            │ conv3_block3_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block4_0_bn   │ (None, 28, 28,    │        896 │ conv3_block3_con… │
│ (BatchNormalizatio… │ 224)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block4_0_relu │ (None, 28, 28,    │          0 │ conv3_block4_0_b… │
│ (Activation)        │ 224)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block4_1_conv │ (None, 28, 28,    │     28,672 │ conv3_block4_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block4_1_bn   │ (None, 28, 28,    │        512 │ conv3_block4_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block4_1_relu │ (None, 28, 28,    │          0 │ conv3_block4_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block4_2_conv │ (None, 28, 28,    │     36,864 │ conv3_block4_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block4_concat │ (None, 28, 28,    │          0 │ conv3_block3_con… │
│ (Concatenate)       │ 256)              │            │ conv3_block4_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block5_0_bn   │ (None, 28, 28,    │      1,024 │ conv3_block4_con… │
│ (BatchNormalizatio… │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block5_0_relu │ (None, 28, 28,    │          0 │ conv3_block5_0_b… │
│ (Activation)        │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block5_1_conv │ (None, 28, 28,    │     32,768 │ conv3_block5_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block5_1_bn   │ (None, 28, 28,    │        512 │ conv3_block5_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block5_1_relu │ (None, 28, 28,    │          0 │ conv3_block5_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block5_2_conv │ (None, 28, 28,    │     36,864 │ conv3_block5_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block5_concat │ (None, 28, 28,    │          0 │ conv3_block4_con… │
│ (Concatenate)       │ 288)              │            │ conv3_block5_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block6_0_bn   │ (None, 28, 28,    │      1,152 │ conv3_block5_con… │
│ (BatchNormalizatio… │ 288)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block6_0_relu │ (None, 28, 28,    │          0 │ conv3_block6_0_b… │
│ (Activation)        │ 288)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block6_1_conv │ (None, 28, 28,    │     36,864 │ conv3_block6_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block6_1_bn   │ (None, 28, 28,    │        512 │ conv3_block6_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block6_1_relu │ (None, 28, 28,    │          0 │ conv3_block6_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block6_2_conv │ (None, 28, 28,    │     36,864 │ conv3_block6_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block6_concat │ (None, 28, 28,    │          0 │ conv3_block5_con… │
│ (Concatenate)       │ 320)              │            │ conv3_block6_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block7_0_bn   │ (None, 28, 28,    │      1,280 │ conv3_block6_con… │
│ (BatchNormalizatio… │ 320)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block7_0_relu │ (None, 28, 28,    │          0 │ conv3_block7_0_b… │
│ (Activation)        │ 320)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block7_1_conv │ (None, 28, 28,    │     40,960 │ conv3_block7_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block7_1_bn   │ (None, 28, 28,    │        512 │ conv3_block7_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block7_1_relu │ (None, 28, 28,    │          0 │ conv3_block7_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block7_2_conv │ (None, 28, 28,    │     36,864 │ conv3_block7_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block7_concat │ (None, 28, 28,    │          0 │ conv3_block6_con… │
│ (Concatenate)       │ 352)              │            │ conv3_block7_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block8_0_bn   │ (None, 28, 28,    │      1,408 │ conv3_block7_con… │
│ (BatchNormalizatio… │ 352)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block8_0_relu │ (None, 28, 28,    │          0 │ conv3_block8_0_b… │
│ (Activation)        │ 352)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block8_1_conv │ (None, 28, 28,    │     45,056 │ conv3_block8_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block8_1_bn   │ (None, 28, 28,    │        512 │ conv3_block8_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block8_1_relu │ (None, 28, 28,    │          0 │ conv3_block8_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block8_2_conv │ (None, 28, 28,    │     36,864 │ conv3_block8_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block8_concat │ (None, 28, 28,    │          0 │ conv3_block7_con… │
│ (Concatenate)       │ 384)              │            │ conv3_block8_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block9_0_bn   │ (None, 28, 28,    │      1,536 │ conv3_block8_con… │
│ (BatchNormalizatio… │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block9_0_relu │ (None, 28, 28,    │          0 │ conv3_block9_0_b… │
│ (Activation)        │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block9_1_conv │ (None, 28, 28,    │     49,152 │ conv3_block9_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block9_1_bn   │ (None, 28, 28,    │        512 │ conv3_block9_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block9_1_relu │ (None, 28, 28,    │          0 │ conv3_block9_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block9_2_conv │ (None, 28, 28,    │     36,864 │ conv3_block9_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block9_concat │ (None, 28, 28,    │          0 │ conv3_block8_con… │
│ (Concatenate)       │ 416)              │            │ conv3_block9_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block10_0_bn  │ (None, 28, 28,    │      1,664 │ conv3_block9_con… │
│ (BatchNormalizatio… │ 416)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block10_0_re… │ (None, 28, 28,    │          0 │ conv3_block10_0_… │
│ (Activation)        │ 416)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block10_1_co… │ (None, 28, 28,    │     53,248 │ conv3_block10_0_… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block10_1_bn  │ (None, 28, 28,    │        512 │ conv3_block10_1_… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block10_1_re… │ (None, 28, 28,    │          0 │ conv3_block10_1_… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block10_2_co… │ (None, 28, 28,    │     36,864 │ conv3_block10_1_… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block10_conc… │ (None, 28, 28,    │          0 │ conv3_block9_con… │
│ (Concatenate)       │ 448)              │            │ conv3_block10_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block11_0_bn  │ (None, 28, 28,    │      1,792 │ conv3_block10_co… │
│ (BatchNormalizatio… │ 448)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block11_0_re… │ (None, 28, 28,    │          0 │ conv3_block11_0_… │
│ (Activation)        │ 448)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block11_1_co… │ (None, 28, 28,    │     57,344 │ conv3_block11_0_… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block11_1_bn  │ (None, 28, 28,    │        512 │ conv3_block11_1_… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block11_1_re… │ (None, 28, 28,    │          0 │ conv3_block11_1_… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block11_2_co… │ (None, 28, 28,    │     36,864 │ conv3_block11_1_… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block11_conc… │ (None, 28, 28,    │          0 │ conv3_block10_co… │
│ (Concatenate)       │ 480)              │            │ conv3_block11_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block12_0_bn  │ (None, 28, 28,    │      1,920 │ conv3_block11_co… │
│ (BatchNormalizatio… │ 480)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block12_0_re… │ (None, 28, 28,    │          0 │ conv3_block12_0_… │
│ (Activation)        │ 480)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block12_1_co… │ (None, 28, 28,    │     61,440 │ conv3_block12_0_… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block12_1_bn  │ (None, 28, 28,    │        512 │ conv3_block12_1_… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block12_1_re… │ (None, 28, 28,    │          0 │ conv3_block12_1_… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block12_2_co… │ (None, 28, 28,    │     36,864 │ conv3_block12_1_… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block12_conc… │ (None, 28, 28,    │          0 │ conv3_block11_co… │
│ (Concatenate)       │ 512)              │            │ conv3_block12_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ pool3_bn            │ (None, 28, 28,    │      2,048 │ conv3_block12_co… │
│ (BatchNormalizatio… │ 512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ pool3_relu          │ (None, 28, 28,    │          0 │ pool3_bn[0][0]    │
│ (Activation)        │ 512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ pool3_conv (Conv2D) │ (None, 28, 28,    │    131,072 │ pool3_relu[0][0]  │
│                     │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ pool3_pool          │ (None, 14, 14,    │          0 │ pool3_conv[0][0]  │
│ (AveragePooling2D)  │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_0_bn   │ (None, 14, 14,    │      1,024 │ pool3_pool[0][0]  │
│ (BatchNormalizatio… │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_0_relu │ (None, 14, 14,    │          0 │ conv4_block1_0_b… │
│ (Activation)        │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_1_conv │ (None, 14, 14,    │     32,768 │ conv4_block1_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_1_bn   │ (None, 14, 14,    │        512 │ conv4_block1_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_1_relu │ (None, 14, 14,    │          0 │ conv4_block1_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_2_conv │ (None, 14, 14,    │     36,864 │ conv4_block1_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_concat │ (None, 14, 14,    │          0 │ pool3_pool[0][0], │
│ (Concatenate)       │ 288)              │            │ conv4_block1_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block2_0_bn   │ (None, 14, 14,    │      1,152 │ conv4_block1_con… │
│ (BatchNormalizatio… │ 288)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block2_0_relu │ (None, 14, 14,    │          0 │ conv4_block2_0_b… │
│ (Activation)        │ 288)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block2_1_conv │ (None, 14, 14,    │     36,864 │ conv4_block2_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block2_1_bn   │ (None, 14, 14,    │        512 │ conv4_block2_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block2_1_relu │ (None, 14, 14,    │          0 │ conv4_block2_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block2_2_conv │ (None, 14, 14,    │     36,864 │ conv4_block2_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block2_concat │ (None, 14, 14,    │          0 │ conv4_block1_con… │
│ (Concatenate)       │ 320)              │            │ conv4_block2_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block3_0_bn   │ (None, 14, 14,    │      1,280 │ conv4_block2_con… │
│ (BatchNormalizatio… │ 320)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block3_0_relu │ (None, 14, 14,    │          0 │ conv4_block3_0_b… │
│ (Activation)        │ 320)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block3_1_conv │ (None, 14, 14,    │     40,960 │ conv4_block3_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block3_1_bn   │ (None, 14, 14,    │        512 │ conv4_block3_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block3_1_relu │ (None, 14, 14,    │          0 │ conv4_block3_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block3_2_conv │ (None, 14, 14,    │     36,864 │ conv4_block3_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block3_concat │ (None, 14, 14,    │          0 │ conv4_block2_con… │
│ (Concatenate)       │ 352)              │            │ conv4_block3_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block4_0_bn   │ (None, 14, 14,    │      1,408 │ conv4_block3_con… │
│ (BatchNormalizatio… │ 352)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block4_0_relu │ (None, 14, 14,    │          0 │ conv4_block4_0_b… │
│ (Activation)        │ 352)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block4_1_conv │ (None, 14, 14,    │     45,056 │ conv4_block4_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block4_1_bn   │ (None, 14, 14,    │        512 │ conv4_block4_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block4_1_relu │ (None, 14, 14,    │          0 │ conv4_block4_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block4_2_conv │ (None, 14, 14,    │     36,864 │ conv4_block4_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block4_concat │ (None, 14, 14,    │          0 │ conv4_block3_con… │
│ (Concatenate)       │ 384)              │            │ conv4_block4_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block5_0_bn   │ (None, 14, 14,    │      1,536 │ conv4_block4_con… │
│ (BatchNormalizatio… │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block5_0_relu │ (None, 14, 14,    │          0 │ conv4_block5_0_b… │
│ (Activation)        │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block5_1_conv │ (None, 14, 14,    │     49,152 │ conv4_block5_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block5_1_bn   │ (None, 14, 14,    │        512 │ conv4_block5_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block5_1_relu │ (None, 14, 14,    │          0 │ conv4_block5_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block5_2_conv │ (None, 14, 14,    │     36,864 │ conv4_block5_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block5_concat │ (None, 14, 14,    │          0 │ conv4_block4_con… │
│ (Concatenate)       │ 416)              │            │ conv4_block5_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block6_0_bn   │ (None, 14, 14,    │      1,664 │ conv4_block5_con… │
│ (BatchNormalizatio… │ 416)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block6_0_relu │ (None, 14, 14,    │          0 │ conv4_block6_0_b… │
│ (Activation)        │ 416)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block6_1_conv │ (None, 14, 14,    │     53,248 │ conv4_block6_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block6_1_bn   │ (None, 14, 14,    │        512 │ conv4_block6_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block6_1_relu │ (None, 14, 14,    │          0 │ conv4_block6_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block6_2_conv │ (None, 14, 14,    │     36,864 │ conv4_block6_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block6_concat │ (None, 14, 14,    │          0 │ conv4_block5_con… │
│ (Concatenate)       │ 448)              │            │ conv4_block6_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block7_0_bn   │ (None, 14, 14,    │      1,792 │ conv4_block6_con… │
│ (BatchNormalizatio… │ 448)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block7_0_relu │ (None, 14, 14,    │          0 │ conv4_block7_0_b… │
│ (Activation)        │ 448)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block7_1_conv │ (None, 14, 14,    │     57,344 │ conv4_block7_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block7_1_bn   │ (None, 14, 14,    │        512 │ conv4_block7_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block7_1_relu │ (None, 14, 14,    │          0 │ conv4_block7_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block7_2_conv │ (None, 14, 14,    │     36,864 │ conv4_block7_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block7_concat │ (None, 14, 14,    │          0 │ conv4_block6_con… │
│ (Concatenate)       │ 480)              │            │ conv4_block7_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block8_0_bn   │ (None, 14, 14,    │      1,920 │ conv4_block7_con… │
│ (BatchNormalizatio… │ 480)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block8_0_relu │ (None, 14, 14,    │          0 │ conv4_block8_0_b… │
│ (Activation)        │ 480)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block8_1_conv │ (None, 14, 14,    │     61,440 │ conv4_block8_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block8_1_bn   │ (None, 14, 14,    │        512 │ conv4_block8_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block8_1_relu │ (None, 14, 14,    │          0 │ conv4_block8_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block8_2_conv │ (None, 14, 14,    │     36,864 │ conv4_block8_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block8_concat │ (None, 14, 14,    │          0 │ conv4_block7_con… │
│ (Concatenate)       │ 512)              │            │ conv4_block8_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block9_0_bn   │ (None, 14, 14,    │      2,048 │ conv4_block8_con… │
│ (BatchNormalizatio… │ 512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block9_0_relu │ (None, 14, 14,    │          0 │ conv4_block9_0_b… │
│ (Activation)        │ 512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block9_1_conv │ (None, 14, 14,    │     65,536 │ conv4_block9_0_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block9_1_bn   │ (None, 14, 14,    │        512 │ conv4_block9_1_c… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block9_1_relu │ (None, 14, 14,    │          0 │ conv4_block9_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block9_2_conv │ (None, 14, 14,    │     36,864 │ conv4_block9_1_r… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block9_concat │ (None, 14, 14,    │          0 │ conv4_block8_con… │
│ (Concatenate)       │ 544)              │            │ conv4_block9_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block10_0_bn  │ (None, 14, 14,    │      2,176 │ conv4_block9_con… │
│ (BatchNormalizatio… │ 544)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block10_0_re… │ (None, 14, 14,    │          0 │ conv4_block10_0_… │
│ (Activation)        │ 544)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block10_1_co… │ (None, 14, 14,    │     69,632 │ conv4_block10_0_… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block10_1_bn  │ (None, 14, 14,    │        512 │ conv4_block10_1_… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block10_1_re… │ (None, 14, 14,    │          0 │ conv4_block10_1_… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block10_2_co… │ (None, 14, 14,    │     36,864 │ conv4_block10_1_… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block10_conc… │ (None, 14, 14,    │          0 │ conv4_block9_con… │
│ (Concatenate)       │ 576)              │            │ conv4_block10_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block11_0_bn  │ (None, 14, 14,    │      2,304 │ conv4_block10_co… │
│ (BatchNormalizatio… │ 576)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block11_0_re… │ (None, 14, 14,    │          0 │ conv4_block11_0_… │
│ (Activation)        │ 576)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block11_1_co… │ (None, 14, 14,    │     73,728 │ conv4_block11_0_… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block11_1_bn  │ (None, 14, 14,    │        512 │ conv4_block11_1_… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block11_1_re… │ (None, 14, 14,    │          0 │ conv4_block11_1_… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block11_2_co… │ (None, 14, 14,    │     36,864 │ conv4_block11_1_… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block11_conc… │ (None, 14, 14,    │          0 │ conv4_block10_co… │
│ (Concatenate)       │ 608)              │            │ conv4_block11_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block12_0_bn  │ (None, 14, 14,    │      2,432 │ conv4_block11_co… │
│ (BatchNormalizatio… │ 608)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block12_0_re… │ (None, 14, 14,    │          0 │ conv4_block12_0_… │
│ (Activation)        │ 608)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block12_1_co… │ (None, 14, 14,    │     77,824 │ conv4_block12_0_… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block12_1_bn  │ (None, 14, 14,    │        512 │ conv4_block12_1_… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block12_1_re… │ (None, 14, 14,    │          0 │ conv4_block12_1_… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block12_2_co… │ (None, 14, 14,    │     36,864 │ conv4_block12_1_… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block12_conc… │ (None, 14, 14,    │          0 │ conv4_block11_co… │
│ (Concatenate)       │ 640)              │            │ conv4_block12_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block13_0_bn  │ (None, 14, 14,    │      2,560 │ conv4_block12_co… │
│ (BatchNormalizatio… │ 640)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block13_0_re… │ (None, 14, 14,    │          0 │ conv4_block13_0_… │
│ (Activation)        │ 640)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block13_1_co… │ (None, 14, 14,    │     81,920 │ conv4_block13_0_… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block13_1_bn  │ (None, 14, 14,    │        512 │ conv4_block13_1_… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block13_1_re… │ (None, 14, 14,    │          0 │ conv4_block13_1_… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block13_2_co… │ (None, 14, 14,    │     36,864 │ conv4_block13_1_… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block13_conc… │ (None, 14, 14,    │          0 │ conv4_block12_co… │
│ (Concatenate)       │ 672)              │            │ conv4_block13_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block14_0_bn  │ (None, 14, 14,    │      2,688 │ conv4_block13_co… │
│ (BatchNormalizatio… │ 672)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block14_0_re… │ (None, 14, 14,    │          0 │ conv4_block14_0_… │
│ (Activation)        │ 672)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block14_1_co… │ (None, 14, 14,    │     86,016 │ conv4_block14_0_… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block14_1_bn  │ (None, 14, 14,    │        512 │ conv4_block14_1_… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block14_1_re… │ (None, 14, 14,    │          0 │ conv4_block14_1_… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block14_2_co… │ (None, 14, 14,    │     36,864 │ conv4_block14_1_… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block14_conc… │ (None, 14, 14,    │          0 │ conv4_block13_co… │
│ (Concatenate)       │ 704)              │            │ conv4_block14_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block15_0_bn  │ (None, 14, 14,    │      2,816 │ conv4_block14_co… │
│ (BatchNormalizatio… │ 704)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block15_0_re… │ (None, 14, 14,    │          0 │ conv4_block15_0_… │
│ (Activation)        │ 704)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block15_1_co… │ (None, 14, 14,    │     90,112 │ conv4_block15_0_… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block15_1_bn  │ (None, 14, 14,    │        512 │ conv4_block15_1_… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block15_1_re… │ (None, 14, 14,    │          0 │ conv4_block15_1_… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block15_2_co… │ (None, 14, 14,    │     36,864 │ conv4_block15_1_… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block15_conc… │ (None, 14, 14,    │          0 │ conv4_block14_co… │
│ (Concatenate)       │ 736)              │            │ conv4_block15_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block16_0_bn  │ (None, 14, 14,    │      2,944 │ conv4_block15_co… │
│ (BatchNormalizatio… │ 736)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block16_0_re… │ (None, 14, 14,    │          0 │ conv4_block16_0_… │
│ (Activation)        │ 736)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block16_1_co… │ (None, 14, 14,    │     94,208 │ conv4_block16_0_… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block16_1_bn  │ (None, 14, 14,    │        512 │ conv4_block16_1_… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block16_1_re… │ (None, 14, 14,    │          0 │ conv4_block16_1_… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block16_2_co… │ (None, 14, 14,    │     36,864 │ conv4_block16_1_… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block16_conc… │ (None, 14, 14,    │          0 │ conv4_block15_co… │
│ (Concatenate)       │ 768)              │            │ conv4_block16_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block17_0_bn  │ (None, 14, 14,    │      3,072 │ conv4_block16_co… │
│ (BatchNormalizatio… │ 768)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block17_0_re… │ (None, 14, 14,    │          0 │ conv4_block17_0_… │
│ (Activation)        │ 768)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block17_1_co… │ (None, 14, 14,    │     98,304 │ conv4_block17_0_… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block17_1_bn  │ (None, 14, 14,    │        512 │ conv4_block17_1_… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block17_1_re… │ (None, 14, 14,    │          0 │ conv4_block17_1_… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block17_2_co… │ (None, 14, 14,    │     36,864 │ conv4_block17_1_… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block17_conc… │ (None, 14, 14,    │          0 │ conv4_block16_co… │
│ (Concatenate)       │ 800)              │            │ conv4_block17_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block18_0_bn  │ (None, 14, 14,    │      3,200 │ conv4_block17_co… │
│ (BatchNormalizatio… │ 800)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block18_0_re… │ (None, 14, 14,    │          0 │ conv4_block18_0_… │
│ (Activation)        │ 800)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block18_1_co… │ (None, 14, 14,    │    102,400 │ conv4_block18_0_… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block18_1_bn  │ (None, 14, 14,    │        512 │ conv4_block18_1_… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block18_1_re… │ (None, 14, 14,    │          0 │ conv4_block18_1_… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block18_2_co… │ (None, 14, 14,    │     36,864 │ conv4_block18_1_… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block18_conc… │ (None, 14, 14,    │          0 │ conv4_block17_co… │
│ (Concatenate)       │ 832)              │            │ conv4_block18_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block19_0_bn  │ (None, 14, 14,    │      3,328 │ conv4_block18_co… │
│ (BatchNormalizatio… │ 832)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block19_0_re… │ (None, 14, 14,    │          0 │ conv4_block19_0_… │
│ (Activation)        │ 832)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block19_1_co… │ (None, 14, 14,    │    106,496 │ conv4_block19_0_… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block19_1_bn  │ (None, 14, 14,    │        512 │ conv4_block19_1_… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block19_1_re… │ (None, 14, 14,    │          0 │ conv4_block19_1_… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block19_2_co… │ (None, 14, 14,    │     36,864 │ conv4_block19_1_… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block19_conc… │ (None, 14, 14,    │          0 │ conv4_block18_co… │
│ (Concatenate)       │ 864)              │            │ conv4_block19_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block20_0_bn  │ (None, 14, 14,    │      3,456 │ conv4_block19_co… │
│ (BatchNormalizatio… │ 864)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block20_0_re… │ (None, 14, 14,    │          0 │ conv4_block20_0_… │
│ (Activation)        │ 864)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block20_1_co… │ (None, 14, 14,    │    110,592 │ conv4_block20_0_… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block20_1_bn  │ (None, 14, 14,    │        512 │ conv4_block20_1_… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block20_1_re… │ (None, 14, 14,    │          0 │ conv4_block20_1_… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block20_2_co… │ (None, 14, 14,    │     36,864 │ conv4_block20_1_… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block20_conc… │ (None, 14, 14,    │          0 │ conv4_block19_co… │
│ (Concatenate)       │ 896)              │            │ conv4_block20_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block21_0_bn  │ (None, 14, 14,    │      3,584 │ conv4_block20_co… │
│ (BatchNormalizatio… │ 896)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block21_0_re… │ (None, 14, 14,    │          0 │ conv4_block21_0_… │
│ (Activation)        │ 896)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block21_1_co… │ (None, 14, 14,    │    114,688 │ conv4_block21_0_… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block21_1_bn  │ (None, 14, 14,    │        512 │ conv4_block21_1_… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block21_1_re… │ (None, 14, 14,    │          0 │ conv4_block21_1_… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block21_2_co… │ (None, 14, 14,    │     36,864 │ conv4_block21_1_… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block21_conc… │ (None, 14, 14,    │          0 │ conv4_block20_co… │
│ (Concatenate)       │ 928)              │            │ conv4_block21_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block22_0_bn  │ (None, 14, 14,    │      3,712 │ conv4_block21_co… │
│ (BatchNormalizatio… │ 928)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block22_0_re… │ (None, 14, 14,    │          0 │ conv4_block22_0_… │
│ (Activation)        │ 928)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block22_1_co… │ (None, 14, 14,    │    118,784 │ conv4_block22_0_… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block22_1_bn  │ (None, 14, 14,    │        512 │ conv4_block22_1_… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block22_1_re… │ (None, 14, 14,    │          0 │ conv4_block22_1_… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block22_2_co… │ (None, 14, 14,    │     36,864 │ conv4_block22_1_… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block22_conc… │ (None, 14, 14,    │          0 │ conv4_block21_co… │
│ (Concatenate)       │ 960)              │            │ conv4_block22_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block23_0_bn  │ (None, 14, 14,    │      3,840 │ conv4_block22_co… │
│ (BatchNormalizatio… │ 960)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block23_0_re… │ (None, 14, 14,    │          0 │ conv4_block23_0_… │
│ (Activation)        │ 960)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block23_1_co… │ (None, 14, 14,    │    122,880 │ conv4_block23_0_… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block23_1_bn  │ (None, 14, 14,    │        512 │ conv4_block23_1_… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block23_1_re… │ (None, 14, 14,    │          0 │ conv4_block23_1_… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block23_2_co… │ (None, 14, 14,    │     36,864 │ conv4_block23_1_… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block23_conc… │ (None, 14, 14,    │          0 │ conv4_block22_co… │
│ (Concatenate)       │ 992)              │            │ conv4_block23_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block24_0_bn  │ (None, 14, 14,    │      3,968 │ conv4_block23_co… │
│ (BatchNormalizatio… │ 992)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block24_0_re… │ (None, 14, 14,    │          0 │ conv4_block24_0_… │
│ (Activation)        │ 992)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block24_1_co… │ (None, 14, 14,    │    126,976 │ conv4_block24_0_… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block24_1_bn  │ (None, 14, 14,    │        512 │ conv4_block24_1_… │
│ (BatchNormalizatio… │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block24_1_re… │ (None, 14, 14,    │          0 │ conv4_block24_1_… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block24_2_co… │ (None, 14, 14,    │     36,864 │ conv4_block24_1_… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block24_conc… │ (None, 14, 14,    │          0 │ conv4_block23_co… │
│ (Concatenate)       │ 1024)             │            │ conv4_block24_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ pool4_bn            │ (None, 14, 14,    │      4,096 │ conv4_block24_co… │
│ (BatchNormalizatio… │ 1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ pool4_relu          │ (None, 14, 14,    │          0 │ pool4_bn[0][0]    │
│ (Activation)        │ 1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ pool4_conv (Conv2D) │ (None, 14, 14,    │    524,288 │ pool4_relu[0][0]  │
│                     │ 512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ pool4_pool          │ (None, 7, 7, 512) │          0 │ pool4_conv[0][0]  │
│ (AveragePooling2D)  │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_0_bn   │ (None, 7, 7, 512) │      2,048 │ pool4_pool[0][0]  │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_0_relu │ (None, 7, 7, 512) │          0 │ conv5_block1_0_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_1_conv │ (None, 7, 7, 128) │     65,536 │ conv5_block1_0_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_1_bn   │ (None, 7, 7, 128) │        512 │ conv5_block1_1_c… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_1_relu │ (None, 7, 7, 128) │          0 │ conv5_block1_1_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_2_conv │ (None, 7, 7, 32)  │     36,864 │ conv5_block1_1_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_concat │ (None, 7, 7, 544) │          0 │ pool4_pool[0][0], │
│ (Concatenate)       │                   │            │ conv5_block1_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block2_0_bn   │ (None, 7, 7, 544) │      2,176 │ conv5_block1_con… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block2_0_relu │ (None, 7, 7, 544) │          0 │ conv5_block2_0_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block2_1_conv │ (None, 7, 7, 128) │     69,632 │ conv5_block2_0_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block2_1_bn   │ (None, 7, 7, 128) │        512 │ conv5_block2_1_c… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block2_1_relu │ (None, 7, 7, 128) │          0 │ conv5_block2_1_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block2_2_conv │ (None, 7, 7, 32)  │     36,864 │ conv5_block2_1_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block2_concat │ (None, 7, 7, 576) │          0 │ conv5_block1_con… │
│ (Concatenate)       │                   │            │ conv5_block2_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block3_0_bn   │ (None, 7, 7, 576) │      2,304 │ conv5_block2_con… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block3_0_relu │ (None, 7, 7, 576) │          0 │ conv5_block3_0_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block3_1_conv │ (None, 7, 7, 128) │     73,728 │ conv5_block3_0_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block3_1_bn   │ (None, 7, 7, 128) │        512 │ conv5_block3_1_c… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block3_1_relu │ (None, 7, 7, 128) │          0 │ conv5_block3_1_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block3_2_conv │ (None, 7, 7, 32)  │     36,864 │ conv5_block3_1_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block3_concat │ (None, 7, 7, 608) │          0 │ conv5_block2_con… │
│ (Concatenate)       │                   │            │ conv5_block3_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block4_0_bn   │ (None, 7, 7, 608) │      2,432 │ conv5_block3_con… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block4_0_relu │ (None, 7, 7, 608) │          0 │ conv5_block4_0_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block4_1_conv │ (None, 7, 7, 128) │     77,824 │ conv5_block4_0_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block4_1_bn   │ (None, 7, 7, 128) │        512 │ conv5_block4_1_c… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block4_1_relu │ (None, 7, 7, 128) │          0 │ conv5_block4_1_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block4_2_conv │ (None, 7, 7, 32)  │     36,864 │ conv5_block4_1_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block4_concat │ (None, 7, 7, 640) │          0 │ conv5_block3_con… │
│ (Concatenate)       │                   │            │ conv5_block4_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block5_0_bn   │ (None, 7, 7, 640) │      2,560 │ conv5_block4_con… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block5_0_relu │ (None, 7, 7, 640) │          0 │ conv5_block5_0_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block5_1_conv │ (None, 7, 7, 128) │     81,920 │ conv5_block5_0_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block5_1_bn   │ (None, 7, 7, 128) │        512 │ conv5_block5_1_c… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block5_1_relu │ (None, 7, 7, 128) │          0 │ conv5_block5_1_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block5_2_conv │ (None, 7, 7, 32)  │     36,864 │ conv5_block5_1_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block5_concat │ (None, 7, 7, 672) │          0 │ conv5_block4_con… │
│ (Concatenate)       │                   │            │ conv5_block5_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block6_0_bn   │ (None, 7, 7, 672) │      2,688 │ conv5_block5_con… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block6_0_relu │ (None, 7, 7, 672) │          0 │ conv5_block6_0_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block6_1_conv │ (None, 7, 7, 128) │     86,016 │ conv5_block6_0_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block6_1_bn   │ (None, 7, 7, 128) │        512 │ conv5_block6_1_c… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block6_1_relu │ (None, 7, 7, 128) │          0 │ conv5_block6_1_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block6_2_conv │ (None, 7, 7, 32)  │     36,864 │ conv5_block6_1_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block6_concat │ (None, 7, 7, 704) │          0 │ conv5_block5_con… │
│ (Concatenate)       │                   │            │ conv5_block6_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block7_0_bn   │ (None, 7, 7, 704) │      2,816 │ conv5_block6_con… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block7_0_relu │ (None, 7, 7, 704) │          0 │ conv5_block7_0_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block7_1_conv │ (None, 7, 7, 128) │     90,112 │ conv5_block7_0_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block7_1_bn   │ (None, 7, 7, 128) │        512 │ conv5_block7_1_c… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block7_1_relu │ (None, 7, 7, 128) │          0 │ conv5_block7_1_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block7_2_conv │ (None, 7, 7, 32)  │     36,864 │ conv5_block7_1_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block7_concat │ (None, 7, 7, 736) │          0 │ conv5_block6_con… │
│ (Concatenate)       │                   │            │ conv5_block7_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block8_0_bn   │ (None, 7, 7, 736) │      2,944 │ conv5_block7_con… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block8_0_relu │ (None, 7, 7, 736) │          0 │ conv5_block8_0_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block8_1_conv │ (None, 7, 7, 128) │     94,208 │ conv5_block8_0_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block8_1_bn   │ (None, 7, 7, 128) │        512 │ conv5_block8_1_c… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block8_1_relu │ (None, 7, 7, 128) │          0 │ conv5_block8_1_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block8_2_conv │ (None, 7, 7, 32)  │     36,864 │ conv5_block8_1_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block8_concat │ (None, 7, 7, 768) │          0 │ conv5_block7_con… │
│ (Concatenate)       │                   │            │ conv5_block8_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block9_0_bn   │ (None, 7, 7, 768) │      3,072 │ conv5_block8_con… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block9_0_relu │ (None, 7, 7, 768) │          0 │ conv5_block9_0_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block9_1_conv │ (None, 7, 7, 128) │     98,304 │ conv5_block9_0_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block9_1_bn   │ (None, 7, 7, 128) │        512 │ conv5_block9_1_c… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block9_1_relu │ (None, 7, 7, 128) │          0 │ conv5_block9_1_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block9_2_conv │ (None, 7, 7, 32)  │     36,864 │ conv5_block9_1_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block9_concat │ (None, 7, 7, 800) │          0 │ conv5_block8_con… │
│ (Concatenate)       │                   │            │ conv5_block9_2_c… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block10_0_bn  │ (None, 7, 7, 800) │      3,200 │ conv5_block9_con… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block10_0_re… │ (None, 7, 7, 800) │          0 │ conv5_block10_0_… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block10_1_co… │ (None, 7, 7, 128) │    102,400 │ conv5_block10_0_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block10_1_bn  │ (None, 7, 7, 128) │        512 │ conv5_block10_1_… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block10_1_re… │ (None, 7, 7, 128) │          0 │ conv5_block10_1_… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block10_2_co… │ (None, 7, 7, 32)  │     36,864 │ conv5_block10_1_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block10_conc… │ (None, 7, 7, 832) │          0 │ conv5_block9_con… │
│ (Concatenate)       │                   │            │ conv5_block10_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block11_0_bn  │ (None, 7, 7, 832) │      3,328 │ conv5_block10_co… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block11_0_re… │ (None, 7, 7, 832) │          0 │ conv5_block11_0_… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block11_1_co… │ (None, 7, 7, 128) │    106,496 │ conv5_block11_0_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block11_1_bn  │ (None, 7, 7, 128) │        512 │ conv5_block11_1_… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block11_1_re… │ (None, 7, 7, 128) │          0 │ conv5_block11_1_… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block11_2_co… │ (None, 7, 7, 32)  │     36,864 │ conv5_block11_1_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block11_conc… │ (None, 7, 7, 864) │          0 │ conv5_block10_co… │
│ (Concatenate)       │                   │            │ conv5_block11_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block12_0_bn  │ (None, 7, 7, 864) │      3,456 │ conv5_block11_co… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block12_0_re… │ (None, 7, 7, 864) │          0 │ conv5_block12_0_… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block12_1_co… │ (None, 7, 7, 128) │    110,592 │ conv5_block12_0_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block12_1_bn  │ (None, 7, 7, 128) │        512 │ conv5_block12_1_… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block12_1_re… │ (None, 7, 7, 128) │          0 │ conv5_block12_1_… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block12_2_co… │ (None, 7, 7, 32)  │     36,864 │ conv5_block12_1_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block12_conc… │ (None, 7, 7, 896) │          0 │ conv5_block11_co… │
│ (Concatenate)       │                   │            │ conv5_block12_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block13_0_bn  │ (None, 7, 7, 896) │      3,584 │ conv5_block12_co… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block13_0_re… │ (None, 7, 7, 896) │          0 │ conv5_block13_0_… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block13_1_co… │ (None, 7, 7, 128) │    114,688 │ conv5_block13_0_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block13_1_bn  │ (None, 7, 7, 128) │        512 │ conv5_block13_1_… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block13_1_re… │ (None, 7, 7, 128) │          0 │ conv5_block13_1_… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block13_2_co… │ (None, 7, 7, 32)  │     36,864 │ conv5_block13_1_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block13_conc… │ (None, 7, 7, 928) │          0 │ conv5_block12_co… │
│ (Concatenate)       │                   │            │ conv5_block13_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block14_0_bn  │ (None, 7, 7, 928) │      3,712 │ conv5_block13_co… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block14_0_re… │ (None, 7, 7, 928) │          0 │ conv5_block14_0_… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block14_1_co… │ (None, 7, 7, 128) │    118,784 │ conv5_block14_0_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block14_1_bn  │ (None, 7, 7, 128) │        512 │ conv5_block14_1_… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block14_1_re… │ (None, 7, 7, 128) │          0 │ conv5_block14_1_… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block14_2_co… │ (None, 7, 7, 32)  │     36,864 │ conv5_block14_1_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block14_conc… │ (None, 7, 7, 960) │          0 │ conv5_block13_co… │
│ (Concatenate)       │                   │            │ conv5_block14_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block15_0_bn  │ (None, 7, 7, 960) │      3,840 │ conv5_block14_co… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block15_0_re… │ (None, 7, 7, 960) │          0 │ conv5_block15_0_… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block15_1_co… │ (None, 7, 7, 128) │    122,880 │ conv5_block15_0_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block15_1_bn  │ (None, 7, 7, 128) │        512 │ conv5_block15_1_… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block15_1_re… │ (None, 7, 7, 128) │          0 │ conv5_block15_1_… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block15_2_co… │ (None, 7, 7, 32)  │     36,864 │ conv5_block15_1_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block15_conc… │ (None, 7, 7, 992) │          0 │ conv5_block14_co… │
│ (Concatenate)       │                   │            │ conv5_block15_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block16_0_bn  │ (None, 7, 7, 992) │      3,968 │ conv5_block15_co… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block16_0_re… │ (None, 7, 7, 992) │          0 │ conv5_block16_0_… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block16_1_co… │ (None, 7, 7, 128) │    126,976 │ conv5_block16_0_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block16_1_bn  │ (None, 7, 7, 128) │        512 │ conv5_block16_1_… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block16_1_re… │ (None, 7, 7, 128) │          0 │ conv5_block16_1_… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block16_2_co… │ (None, 7, 7, 32)  │     36,864 │ conv5_block16_1_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block16_conc… │ (None, 7, 7,      │          0 │ conv5_block15_co… │
│ (Concatenate)       │ 1024)             │            │ conv5_block16_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ bn                  │ (None, 7, 7,      │      4,096 │ conv5_block16_co… │
│ (BatchNormalizatio… │ 1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ relu (Activation)   │ (None, 7, 7,      │          0 │ bn[0][0]          │
│                     │ 1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ flatten (Flatten)   │ (None, 50176)     │          0 │ relu[0][0]        │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense (Dense)       │ (None, 1024)      │ 51,381,248 │ flatten[0][0]     │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dropout (Dropout)   │ (None, 1024)      │          0 │ dense[0][0]       │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense_1 (Dense)     │ (None, 7)         │      7,175 │ dropout[0][0]     │
└─────────────────────┴───────────────────┴────────────┴───────────────────┘
 Total params: 58,425,927 (222.88 MB)
 Trainable params: 51,388,423 (196.03 MB)
 Non-trainable params: 7,037,504 (26.85 MB)
In [42]:
# compiler le modèle 
optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3)
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False)
metrics=['accuracy']
model.compile(optimizer=optimizer, loss=loss, metrics=metrics, jit_compile=False) 
# "just in time compiler" sur false pour option deterministe et garantir la reproductibilité cf: tf.config.experimental.enable_op_determinism()
In [43]:
# définition des callbacks : ajustements du processus d'entraînement sous certaines conditions
early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_accuracy', patience=es_patience, restore_best_weights=True)
lr_scheduler = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_accuracy', factor=0.1, patience=lr_patience, min_lr=1e-4)
In [44]:
# entraînement
time1 = time.time()
history = model.fit(train_dataset, epochs=nb_epochs, validation_data=val_dataset, 
                    callbacks=[early_stopping, lr_scheduler])
time2 = time.time() - time1
minutes, seconds = divmod(time2, 60)
duration_str = f"{int(minutes)} min {int(seconds)} sec"
Epoch 1/25
2025-01-22 14:51:58.736417: I external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:465] Loaded cuDNN version 8907
23/23 ━━━━━━━━━━━━━━━━━━━━ 26s 437ms/step - accuracy: 0.3819 - loss: 30.3458 - val_accuracy: 0.8025 - val_loss: 5.9829 - learning_rate: 0.0010
Epoch 2/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 9s 240ms/step - accuracy: 0.8123 - loss: 3.8582 - val_accuracy: 0.8089 - val_loss: 4.8351 - learning_rate: 0.0010
Epoch 3/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 9s 241ms/step - accuracy: 0.8685 - loss: 1.6265 - val_accuracy: 0.8471 - val_loss: 3.6647 - learning_rate: 0.0010
Epoch 4/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 8s 206ms/step - accuracy: 0.9212 - loss: 0.6575 - val_accuracy: 0.8153 - val_loss: 3.6242 - learning_rate: 0.0010
Epoch 5/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 8s 205ms/step - accuracy: 0.9329 - loss: 0.5009 - val_accuracy: 0.8408 - val_loss: 3.0076 - learning_rate: 0.0010
Epoch 6/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 8s 201ms/step - accuracy: 0.9440 - loss: 0.4078 - val_accuracy: 0.8408 - val_loss: 2.4041 - learning_rate: 0.0010
Epoch 7/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 9s 237ms/step - accuracy: 0.9643 - loss: 0.1779 - val_accuracy: 0.8535 - val_loss: 2.4172 - learning_rate: 1.0000e-04
Epoch 8/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 8s 206ms/step - accuracy: 0.9872 - loss: 0.0492 - val_accuracy: 0.8535 - val_loss: 2.4874 - learning_rate: 1.0000e-04
Epoch 9/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 8s 201ms/step - accuracy: 0.9843 - loss: 0.0744 - val_accuracy: 0.8471 - val_loss: 2.5003 - learning_rate: 1.0000e-04
Epoch 10/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 8s 205ms/step - accuracy: 0.9922 - loss: 0.0333 - val_accuracy: 0.8535 - val_loss: 2.5061 - learning_rate: 1.0000e-04
Epoch 11/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 8s 205ms/step - accuracy: 0.9791 - loss: 0.0752 - val_accuracy: 0.8535 - val_loss: 2.5313 - learning_rate: 1.0000e-04
Epoch 12/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 9s 239ms/step - accuracy: 0.9898 - loss: 0.0225 - val_accuracy: 0.8599 - val_loss: 2.5172 - learning_rate: 1.0000e-04
Epoch 13/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 8s 206ms/step - accuracy: 0.9928 - loss: 0.0261 - val_accuracy: 0.8535 - val_loss: 2.4844 - learning_rate: 1.0000e-04
Epoch 14/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 8s 203ms/step - accuracy: 0.9895 - loss: 0.0414 - val_accuracy: 0.8535 - val_loss: 2.4522 - learning_rate: 1.0000e-04
Epoch 15/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 8s 204ms/step - accuracy: 0.9929 - loss: 0.0175 - val_accuracy: 0.8535 - val_loss: 2.4085 - learning_rate: 1.0000e-04
Epoch 16/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 8s 205ms/step - accuracy: 0.9960 - loss: 0.0057 - val_accuracy: 0.8535 - val_loss: 2.4104 - learning_rate: 1.0000e-04
Epoch 17/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 8s 201ms/step - accuracy: 0.9981 - loss: 0.0207 - val_accuracy: 0.8535 - val_loss: 2.4278 - learning_rate: 1.0000e-04
Epoch 18/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 8s 205ms/step - accuracy: 0.9930 - loss: 0.0337 - val_accuracy: 0.8599 - val_loss: 2.4557 - learning_rate: 1.0000e-04
Epoch 19/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 8s 203ms/step - accuracy: 0.9958 - loss: 0.0065 - val_accuracy: 0.8599 - val_loss: 2.4706 - learning_rate: 1.0000e-04
Epoch 20/25
23/23 ━━━━━━━━━━━━━━━━━━━━ 8s 200ms/step - accuracy: 0.9972 - loss: 0.0096 - val_accuracy: 0.8535 - val_loss: 2.4705 - learning_rate: 1.0000e-04
In [45]:
plt.figure(figsize=(12, 4))

# visualiser la perte pendant l'apprentissage
plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], label='Train Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.title('Loss Over Epochs')
plt.legend()

# visualiser l'accuracy pendant l'apprentissage
plt.subplot(1, 2, 2)
plt.plot(history.history['accuracy'], label='Train Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.title('Accuracy Over Epochs')
plt.legend()

plt.suptitle("Courbes d'entraînement et de validation lors de l'apprentissage AVEC poids imagenet & SANS data-augmentation")
plt.show()
No description has been provided for this image

Évaluation TRAIN¶

In [46]:
X_train, y_train, y_train_pred_classes = get_predictions(model, train_dataset)
1/1 ━━━━━━━━━━━━━━━━━━━━ 3s 3s/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 108ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 113ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 115ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 111ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 108ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 121ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 121ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 118ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 118ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 109ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 118ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 113ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 116ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 116ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 112ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 137ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 110ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 110ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 117ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 110ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 117ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 3s 3s/step
2025-01-22 14:55:00.549813: W tensorflow/core/framework/local_rendezvous.cc:404] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence
In [47]:
print("Classification Report  - TRAIN - AVEC poids imagenet & SANS data-augmentation :")
print(classification_report(y_train, y_train_pred_classes))
Classification Report  - TRAIN - AVEC poids imagenet & SANS data-augmentation :
              precision    recall  f1-score   support

           0       1.00      1.00      1.00       105
           1       1.00      1.00      1.00       105
           2       1.00      1.00      1.00       105
           3       1.00      1.00      1.00       105
           4       1.00      1.00      1.00       105
           5       1.00      1.00      1.00       105
           6       1.00      1.00      1.00       105

    accuracy                           1.00       735
   macro avg       1.00      1.00      1.00       735
weighted avg       1.00      1.00      1.00       735

In [48]:
conf_matrix_train = confusion_matrix(y_train, y_train_pred_classes)
plot_confusion_matrix(conf_matrix_train, 'TRAIN',  data_augment=False)
No description has been provided for this image

Évaluation VALIDATION¶

In [49]:
X_val, y_val, y_val_pred_classes = get_predictions(model, val_dataset)
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 110ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 104ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 115ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 110ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 108ms/step
2025-01-22 14:55:03.231596: W tensorflow/core/framework/local_rendezvous.cc:404] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence
In [50]:
print("Classification Report  - VALIDATION - AVEC poids imagenet & SANS data-augmentation :")
print(classification_report(y_val, y_val_pred_classes))
Classification Report  - VALIDATION - AVEC poids imagenet & SANS data-augmentation :
              precision    recall  f1-score   support

           0       0.83      0.68      0.75        22
           1       0.77      0.87      0.82        23
           2       0.87      0.87      0.87        23
           3       0.76      0.86      0.81        22
           4       0.95      0.83      0.88        23
           5       0.91      0.91      0.91        22
           6       0.96      1.00      0.98        22

    accuracy                           0.86       157
   macro avg       0.86      0.86      0.86       157
weighted avg       0.86      0.86      0.86       157

In [51]:
conf_matrix_val = confusion_matrix(y_val, y_val_pred_classes)
plot_confusion_matrix(conf_matrix_val, 'VALIDATION',  data_augment=False)
No description has been provided for this image

Évaluation TRAIN+VALIDATION¶

In [52]:
train_val_dataset = train_dataset.concatenate(val_dataset)
loss_trainval, accuracy_trainval = model.evaluate(train_val_dataset)
28/28 ━━━━━━━━━━━━━━━━━━━━ 7s 149ms/step - accuracy: 0.9965 - loss: 0.0652
In [53]:
X_train_val, y_train_val, y_train_val_pred_classes = get_predictions(model, train_val_dataset)
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 106ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 113ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 113ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 115ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 122ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 117ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 106ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 115ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 110ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 109ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 112ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 108ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 104ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 115ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 116ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 114ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 106ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 116ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 105ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 102ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 104ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 104ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 128ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 116ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 118ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 116ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 121ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 113ms/step
2025-01-22 14:55:21.415885: W tensorflow/core/framework/local_rendezvous.cc:404] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence
In [54]:
print("Classification Report  - TRAIN+VALIDATION - AVEC poids imagenet & SANS data-augmentatio :")
print(classification_report(y_train_val, y_train_val_pred_classes))
Classification Report  - TRAIN+VALIDATION - AVEC poids imagenet & SANS data-augmentatio :
              precision    recall  f1-score   support

           0       0.98      0.94      0.96       127
           1       0.95      0.98      0.97       128
           2       0.98      0.98      0.98       128
           3       0.95      0.98      0.96       127
           4       0.99      0.97      0.98       128
           5       0.98      0.98      0.98       127
           6       0.99      1.00      1.00       127

    accuracy                           0.98       892
   macro avg       0.98      0.98      0.98       892
weighted avg       0.98      0.98      0.98       892

In [55]:
conf_matrix_train_val = confusion_matrix(y_train_val, y_train_val_pred_classes)
plot_confusion_matrix(conf_matrix_train_val, 'TRAIN+VALIDATION',  data_augment=False)
No description has been provided for this image

Évaluation TEST¶

In [56]:
loss_test, accuracy_test = model.evaluate(test_dataset)
5/5 ━━━━━━━━━━━━━━━━━━━━ 2s 172ms/step - accuracy: 0.8987 - loss: 1.0929
In [57]:
X_test, y_test ,y_test_pred_classes = get_predictions(model, test_dataset)
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 110ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 112ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 107ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 114ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 101ms/step
2025-01-22 14:55:26.220083: W tensorflow/core/framework/local_rendezvous.cc:404] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence
In [58]:
print("Classification Report - TEST - AVEC poids imagenet & SANS data-augmentation :")
print(classification_report(y_test, y_test_pred_classes))
Classification Report - TEST - AVEC poids imagenet & SANS data-augmentation :
              precision    recall  f1-score   support

           0       0.89      0.74      0.81        23
           1       0.83      0.86      0.84        22
           2       0.88      0.95      0.91        22
           3       0.84      0.91      0.88        23
           4       0.82      0.82      0.82        22
           5       0.95      0.91      0.93        23
           6       1.00      1.00      1.00        23

    accuracy                           0.89       158
   macro avg       0.89      0.89      0.88       158
weighted avg       0.89      0.89      0.89       158

In [59]:
conf_matrix_test = confusion_matrix(y_test, y_test_pred_classes)
plot_confusion_matrix(conf_matrix_test, 'TEST',  data_augment=False)
No description has been provided for this image

Enregistrement des résultats¶

In [60]:
perf_test_df = pd.concat([perf_test_df, pd.DataFrame({'Scenario': ['Baseline_DenseNet121'], 
                                                      'Description': ['AVEC poids imagenet & SANS data-augmentation'], 
                                                      'Accuracy_Train': [accuracy_trainval *100],
                                                      'Accuracy_Test': [accuracy_test *100], 
                                                      'Durée_totale_computation': [duration_str]})], ignore_index=True)
perf_test_df
/tmp/ipykernel_911805/1169499322.py:1: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.
  perf_test_df = pd.concat([perf_test_df, pd.DataFrame({'Scenario': ['Baseline_DenseNet121'],
Out[60]:
Scenario Description Accuracy_Train Accuracy_Test Durée_totale_computation
0 Baseline_DenseNet121 AVEC poids imagenet & SANS data-augmentation 97.533631 88.607597 3 min 2 sec

Visualisation des images bien et mal classées sur le TEST¶

In [61]:
visualisation_images_TEST('BIEN', y_test, y_test_pred_classes, X_test, dict_label=label_to_category, num_examples=6)
visualisation_images_TEST('MAL', y_test, y_test_pred_classes, X_test, dict_label=label_to_category, num_examples=6)
No description has been provided for this image
No description has been provided for this image

TEST - Approche Multimodale avec CLIP¶

1. Données d'entraînement :

  • 400 millions d'images-textes collectées à partir d'Internet
  • Nom du dataset : WIT (WebImageText)

2. Longueur de contexte d'entraînement :

  • Longueur de contexte : 77 tokens

3. Détails des modèles :

  • Il existe plusieur modèles de computer vision disponibles avec CLIP, plusieurs ResNet et plusieurs Vision Transformers.
  • Nous allons tester le modèle Vision Transformer (Base, 32x32 patches), le ViT-B/32.

Architecture : ResNet-50

Imports librairies spécifiques¶

In [62]:
# data & science
import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix

# system & tools
import time
import os
import random

# graphiques
import matplotlib.pyplot as plt
from matplotlib.image import imread
import seaborn as sns
from wordcloud import WordCloud
%matplotlib inline

# natural language processing
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import RegexpTokenizer

# computer vision / CNN
from PIL import Image
import cv2 # OpenCV 

# approche CLIP
import torch
import clip

Reproductibilité des résultats¶

In [63]:
# Seed value
seed_value= 1802

# 1. Set the `PYTHONHASHSEED` environment variable at a fixed value
os.environ['PYTHONHASHSEED']=str(seed_value)
print("os.environ['PYTHONHASHSEED'] == ", os.environ['PYTHONHASHSEED'])

# 2. Set the `python` built-in pseudo-random generator at a fixed value
random.seed(seed_value)

# 3. Set the `numpy` pseudo-random generator at a fixed value
np.random.seed(seed_value)

# 4. Set the `torch` pseudo-random generator at a fixed value
torch.manual_seed(seed_value)

# 5. If you are using CUDA, set the `torch.cuda` pseudo-random generator at a fixed value
if torch.cuda.is_available():
    torch.cuda.manual_seed(seed_value)
    torch.cuda.manual_seed_all(seed_value)  # if you are using multi-GPU.

# 6. Configure PyTorch to use deterministic algorithms
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False

# 7. Vérifier la reproductibilité
random_values_1 = torch.rand(5)
print("PyTorch Valeurs aléatoires 1:", random_values_1.numpy())

## Réinitialiser les graines
torch.manual_seed(seed_value)
if torch.cuda.is_available():
    torch.cuda.manual_seed(seed_value)
    torch.cuda.manual_seed_all(seed_value)  # if you are using multi-GPU.

random_values_2 = torch.rand(5)
print("PyTorch Valeurs aléatoires 2:", random_values_2.numpy())

## Vérifier que les valeurs aléatoires sont identiques
assert np.array_equal(random_values_1.numpy(), random_values_2.numpy()), "PyTorch Les valeurs aléatoires ne sont pas identiques"
print("PyTorch : Les valeurs aléatoires sont identiques, la graine est correctement fixée.")
os.environ['PYTHONHASHSEED'] ==  1802
PyTorch Valeurs aléatoires 1: [0.70822376 0.91128254 0.52850455 0.03241813 0.45658195]
PyTorch Valeurs aléatoires 2: [0.70822376 0.91128254 0.52850455 0.03241813 0.45658195]
PyTorch : Les valeurs aléatoires sont identiques, la graine est correctement fixée.
In [64]:
torch.cuda.memory_summary(device=None, abbreviated=True)
Out[64]:
'|===========================================================================|\n|                  PyTorch CUDA memory summary, device ID 0                 |\n|---------------------------------------------------------------------------|\n|            CUDA OOMs: 0            |        cudaMalloc retries: 0         |\n|===========================================================================|\n|        Metric         | Cur Usage  | Peak Usage | Tot Alloc  | Tot Freed  |\n|---------------------------------------------------------------------------|\n| Allocated memory      |      0 B   |      0 B   |      0 B   |      0 B   |\n|---------------------------------------------------------------------------|\n| Active memory         |      0 B   |      0 B   |      0 B   |      0 B   |\n|---------------------------------------------------------------------------|\n| Requested memory      |      0 B   |      0 B   |      0 B   |      0 B   |\n|---------------------------------------------------------------------------|\n| GPU reserved memory   |      0 B   |      0 B   |      0 B   |      0 B   |\n|---------------------------------------------------------------------------|\n| Non-releasable memory |      0 B   |      0 B   |      0 B   |      0 B   |\n|---------------------------------------------------------------------------|\n| Allocations           |       0    |       0    |       0    |       0    |\n|---------------------------------------------------------------------------|\n| Active allocs         |       0    |       0    |       0    |       0    |\n|---------------------------------------------------------------------------|\n| GPU reserved segments |       0    |       0    |       0    |       0    |\n|---------------------------------------------------------------------------|\n| Non-releasable allocs |       0    |       0    |       0    |       0    |\n|---------------------------------------------------------------------------|\n| Oversize allocations  |       0    |       0    |       0    |       0    |\n|---------------------------------------------------------------------------|\n| Oversize GPU segments |       0    |       0    |       0    |       0    |\n|===========================================================================|\n'
In [65]:
torch.cuda.empty_cache()

Charger le modèle CLIP et le tokenizer associés.¶

In [66]:
torch.cuda.device_count()
Out[66]:
4
In [67]:
os.environ['PYTORCH_CUDA_ALLOC_CONF'] = 'expandable_segments:True'
In [68]:
# Charger le modèle CLIP et le tokenizer
# device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
device = "cpu"
model, preprocess = clip.load("ViT-B/32", device=device)

Vérifier la reproductibilité¶

In [69]:
torch.manual_seed(seed_value)
random_values_1 = torch.rand(5)
print("PyTorch Valeurs aléatoires 1:", random_values_1.numpy())

## Réinitialiser les graines
torch.manual_seed(seed_value)
if torch.cuda.is_available():
    torch.cuda.manual_seed(seed_value)
    torch.cuda.manual_seed_all(seed_value)  # if you are using multi-GPU.

random_values_2 = torch.rand(5)
print("PyTorch Valeurs aléatoires 2:", random_values_2.numpy())

## Vérifier que les valeurs aléatoires sont identiques
assert np.array_equal(random_values_1.numpy(), random_values_2.numpy()), "PyTorch Les valeurs aléatoires ne sont pas identiques"
print("PyTorch : Les valeurs aléatoires sont identiques, la graine est correctement fixée.")
PyTorch Valeurs aléatoires 1: [0.70822376 0.91128254 0.52850455 0.03241813 0.45658195]
PyTorch Valeurs aléatoires 2: [0.70822376 0.91128254 0.52850455 0.03241813 0.45658195]
PyTorch : Les valeurs aléatoires sont identiques, la graine est correctement fixée.

Fonctions¶

In [70]:
#visualiser les images bien et mal classées sur le TEST
def visualisation_images_TEST(etat, y_test, y_test_pred_classes, data_final, test_indices, dict_label, num_examples=6):
    categories = np.unique(y_test)

    # Récupérer les index des images bien et mal classées
    if etat == 'BIEN':
        indices = np.where(y_test_pred_classes == y_test.values)[0]
        title = "TEST - Images BIEN classées"
    elif etat == 'MAL':
        indices = np.where(y_test_pred_classes != y_test.values)[0]
        title = "TEST - Images MAL classées"
    else:
        raise ValueError("L'état doit être 'BIEN' ou 'MAL'")

    # Init dict des exemples
    examples = {category: [] for category in categories}
    # Récupérer les exemples par catégories
    for category in categories:
        category_indices = [idx for idx in indices if y_test.iloc[idx] == category]
        if len(category_indices) >= num_examples:
            examples[category] = category_indices[:num_examples]
        else:
            examples[category] = category_indices

    # Affichage des exemples par catégories
    fig, axes = plt.subplots(len(categories), num_examples, figsize=(num_examples * 3, len(categories) * 3), facecolor='black')
    fig.suptitle(title, color='white', fontsize=16)

    plt.subplots_adjust(hspace=0.5)

    for i, category in enumerate(categories):
        axes[i, 0].annotate(f'Catégorie réelle : {dict_label[category]}', xy=(0, 1), xytext=(0, 1.2),
                            xycoords='axes fraction', textcoords='axes fraction',
                            ha='left', va='bottom', color='white', fontsize=14, annotation_clip=False)

        for j in range(num_examples):
            if j < len(examples[category]):
                idx = examples[category][j]
                original_idx = test_indices[idx]
                image_path = data_final.iloc[original_idx]['reshaped_image_path']
                try:
                    rescaled_image = Image.open(image_path)
                    axes[i, j].imshow(rescaled_image)
                    pred_label = dict_label[y_test_pred_classes[idx]]
                    axes[i, j].set_title(f"Pred: {pred_label}", color='white', fontsize=10)
                except Exception as e:
                    print(f"Erreur lors de l'ouverture de l'image {image_path}: {e}")
            axes[i, j].axis('off')

    plt.show()

    
# Fonction pour obtenir les prédictions du modèle sur un dataset donné
def get_predictions(model, X):
    y_pred = model.predict(X)
    return y_pred

# Fonction pour vérifier la répartition équilibrée des classes après le train_test_split
def check_class_distribution(y_train, y_test, label_to_category):
    # Fonction pour extraire les labels
    def extract_labels(labels):
        return np.array(labels)

    # Labels des datasets
    train_labels = extract_labels(y_train)
    test_labels = extract_labels(y_test)

    # Répartition des classes
    train_counts = np.unique(train_labels, return_counts=True)
    test_counts = np.unique(test_labels, return_counts=True)
    total_counts = np.sum([train_counts[1], test_counts[1]])

    train_total_percentage = (np.sum(train_counts[1]) / total_counts) * 100
    test_total_percentage = (np.sum(test_counts[1]) / total_counts) * 100

    train_percentages = (train_counts[1] / total_counts) * 100
    test_percentages = (test_counts[1] / total_counts) * 100

    # Correspondance avec les noms des catégories
    categories = np.concatenate([train_counts[0], test_counts[0]])
    category_names = [label_to_category[label] for label in categories]

    data = {
        'Catégories': category_names,
        'Pourcentage': np.concatenate([train_percentages, test_percentages]),
        'Ensemble': ['Train'] * len(train_counts[0]) + ['Test'] * len(test_counts[0])
    }
    df_plot = pd.DataFrame(data)

    palette = {'Train': '#1f77b4', 'Test': '#ff7f0e'}
    plt.figure(figsize=(15, 8))
    sns.barplot(x='Catégories', y='Pourcentage', hue='Ensemble', data=df_plot, palette=palette)
    plt.title('Répartition des classes dans les ensembles d\'entraînement et de test')
    plt.xlabel('Catégories')
    plt.ylabel('Pourcentage du dataset total')
    plt.xticks(rotation=45)
    handles, labels = plt.gca().get_legend_handles_labels()
    labels = [
        f'Train - {train_total_percentage:.2f}%',
        f'Test - {test_total_percentage:.2f}%'
    ]
    plt.legend(handles=handles, labels=labels, title='Sous-ensembles totaux')
    plt.show()

A. Approche 1 : Avec les descriptions originelles (non tokenisées)¶

Encoder les images et les descriptions¶

In [71]:
data_final.head(2)
Out[71]:
uniq_id product_name description token_nltk categ_0 label reshaped_image_path
0 55b85ea15a1536d46b7190ad6fff8ce7 Elegance Polyester Multicolor Abstract Eyelet ... Key Features of Elegance Polyester Multicolor ... Key Features of Elegance Polyester Multicolor ... home furnishing 4 ./reshaped_images/55b85ea15a1536d46b7190ad6fff...
1 7b72c92c2f6c40268628ec5f14c6d590 Sathiyas Cotton Bath Towel Specifications of Sathiyas Cotton Bath Towel (... Specifications of Sathiyas Cotton Bath Towel B... baby care 0 ./reshaped_images/7b72c92c2f6c40268628ec5f14c6...
In [72]:
time1 = time.time()
In [73]:
# Prétraiter les images et les descriptions
images = [preprocess(Image.open(image_path)) for image_path in data_final['reshaped_image_path']]
/home/stephanie/miniconda3/envs/env_p6_gpu/lib/python3.11/site-packages/PIL/Image.py:3218: DecompressionBombWarning: Image size (121925764 pixels) exceeds limit of 89478485 pixels, could be decompression bomb DOS attack.
  warnings.warn(
In [74]:
# le modèle CLIP a été pré-entraîné avec une longueur de contexte spécifique (77 tokens pour le modèle ViT-B/32), 
# et changer cette longueur peut affecter les performances du modèle.
max_length = 77
model.context_length = max_length
#texts = clip.tokenize(data_final['token_nltk'].tolist()).to(device)
texts = clip.tokenize(data_final['description'], context_length=model.context_length, truncate=True).squeeze(0)
In [75]:
texts[0]
Out[75]:
tensor([49406,  1458,  4643,   539, 19146, 38514, 21683, 29245, 10197,  5034,
         1094,  2489, 17223, 10732, 17223,   267, 19146, 38514, 21683, 29245,
        10197,  5034,  1094,  2489, 17223,   263,   273,   272,   274,  3741,
          530, 10788,   267,  3420,   539,   273,   264,  2827,   281,  1724,
          269,   279,   280,   280,   589, 17223, 38259,   518,  1012,   539,
          518, 14836,   269,   589, 17223,   533,  1105,   633,   272,   271,
          271,   260,  1400,  3027, 38514, 10033,   269,   585,  4643,   550,
         5034,  1094,  1844, 14771,   593,  4044, 49407], dtype=torch.int32)
In [76]:
# Empiler les images en un seul tenseur
image_input = torch.stack(images).to(device)

# Encoder les images et les descriptions
with torch.no_grad():
    image_features = model.encode_image(image_input)
    text_features = model.encode_text(texts)

# Normaliser les caractéristiques
image_features /= image_features.norm(dim=-1, keepdim=True)
text_features /= text_features.norm(dim=-1, keepdim=True)

Combiner les caractéristiques des images et des textes¶

Combinez les caractéristiques encodées des images et des textes pour former une représentation conjointe.

In [77]:
# Combiner les caractéristiques des images et des textes
#pour cpu
combined_features = torch.cat((image_features, text_features), dim=1).cpu().numpy() 
# # pour gpu
# image_features = image_features.to(device)
# text_features = text_features.to(device)
# # Combiner les caractéristiques des images et des textes sur le GPU
# combined_features = torch.cat((image_features, text_features), dim=1)

Train-Test Split¶

In [78]:
# Diviser les données en ensembles d'entraînement et de test
X_train, X_test, y_train, y_test, train_indices, test_indices = train_test_split(
    combined_features, data_final['label'], data_final.index, 
    test_size=0.2, stratify=data_final['label'], random_state=seed_value)
# Vérifier la répartition des classes
check_class_distribution(y_train, y_test, label_to_category)
No description has been provided for this image

Entraîner un classificateur¶

Utilisez les caractéristiques combinées pour entraîner un classificateur, comme une régression logistique.

In [79]:
# Entraîner un classificateur
classifier = LogisticRegression(max_iter=1000)
classifier.fit(X_train, y_train)
Out[79]:
LogisticRegression(max_iter=1000)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
LogisticRegression(max_iter=1000)
In [80]:
time2 = time.time() - time1
minutes, seconds = divmod(time2, 60)
duration_str = f"{int(minutes)} min {int(seconds)} sec"

Évaluer le classificateur¶

In [81]:
print("Score d'entraînement :", classifier.score(X_train, y_train))
print("Score de test :", classifier.score(X_test, y_test))
Score d'entraînement : 0.9654761904761905
Score de test : 0.9666666666666667

TRAiN¶

In [82]:
y_train_pred_classes = get_predictions(classifier, X_train)
target_names = [label_to_category[label] for label in sorted(label_to_category)]
print(classification_report(y_train, y_train_pred_classes, target_names=target_names))
                            precision    recall  f1-score   support

                 baby care       0.96      0.86      0.91       120
  beauty and personal care       0.97      0.94      0.95       120
                 computers       0.98      1.00      0.99       120
home decor & festive needs       0.95      0.97      0.96       120
           home furnishing       0.92      0.98      0.95       120
          kitchen & dining       0.98      1.00      0.99       120
                   watches       1.00      1.00      1.00       120

                  accuracy                           0.97       840
                 macro avg       0.97      0.97      0.97       840
              weighted avg       0.97      0.97      0.97       840

In [83]:
conf_matrix_train = confusion_matrix(y_train, y_train_pred_classes)
plot_confusion_matrix(conf_matrix_train, 'TRAIN')
No description has been provided for this image

TEST¶

In [84]:
y_test_pred_classes = get_predictions(classifier, X_test)
target_names = [label_to_category[label] for label in sorted(label_to_category)]
print(classification_report(y_test, y_test_pred_classes, target_names=target_names))
                            precision    recall  f1-score   support

                 baby care       0.97      0.97      0.97        30
  beauty and personal care       1.00      0.83      0.91        30
                 computers       0.94      1.00      0.97        30
home decor & festive needs       0.88      1.00      0.94        30
           home furnishing       1.00      1.00      1.00        30
          kitchen & dining       1.00      0.97      0.98        30
                   watches       1.00      1.00      1.00        30

                  accuracy                           0.97       210
                 macro avg       0.97      0.97      0.97       210
              weighted avg       0.97      0.97      0.97       210

In [85]:
conf_matrix_test = confusion_matrix(y_test, y_test_pred_classes)
plot_confusion_matrix(conf_matrix_test, 'TEST')
No description has been provided for this image

Enregistrement des résultats¶

In [86]:
perf_test_df = pd.concat([perf_test_df, pd.DataFrame({'Scenario': ['TEST_CLIP_model_A'], 
                                                      'Description': ['SANS tokenisation NLTK et troncature avec CLIP / CPU'], 
                                                      'Accuracy_Train': [classifier.score(X_train, y_train) *100],
                                                      'Accuracy_Test': [classifier.score(X_test, y_test) *100], 
                                                      'Durée_totale_computation': [duration_str]})], ignore_index=True)
perf_test_df
Out[86]:
Scenario Description Accuracy_Train Accuracy_Test Durée_totale_computation
0 Baseline_DenseNet121 AVEC poids imagenet & SANS data-augmentation 97.533631 88.607597 3 min 2 sec
1 TEST_CLIP_model_A SANS tokenisation NLTK et troncature avec CLIP... 96.547619 96.666667 2 min 40 sec

Visualisation des images bien et mal classées sur le TEST¶

In [87]:
visualisation_images_TEST('BIEN', y_test, y_test_pred_classes, data_final, test_indices, dict_label=label_to_category, num_examples=6)
visualisation_images_TEST('MAL', y_test, y_test_pred_classes, data_final, test_indices, dict_label=label_to_category, num_examples=6)
No description has been provided for this image
No description has been provided for this image

B. Approche 2 : Avec les descriptions issues d'une tokenisation nltk¶

Encoder les images et les descriptions¶

In [88]:
time1 = time.time()
In [89]:
# Prétraiter les images et les descriptions
images = [preprocess(Image.open(image_path)) for image_path in data_final['reshaped_image_path']]
/home/stephanie/miniconda3/envs/env_p6_gpu/lib/python3.11/site-packages/PIL/Image.py:3218: DecompressionBombWarning: Image size (121925764 pixels) exceeds limit of 89478485 pixels, could be decompression bomb DOS attack.
  warnings.warn(
In [90]:
# le modèle CLIP a été pré-entraîné avec une longueur de contexte spécifique (77 tokens pour le modèle ViT-B/32), 
# et changer cette longueur peut affecter les performances du modèle.
max_length = 77
model.context_length = max_length
#texts = clip.tokenize(data_final['token_nltk'].tolist()).to(device)
texts = clip.tokenize(data_final['token_nltk'], context_length=model.context_length, truncate=True).squeeze(0)
In [91]:
texts[0]
Out[91]:
tensor([49406,  1458,  4643,   539, 19146, 38514, 21683, 29245, 10197,  5034,
         1094,  2489, 17223, 10732, 17223, 19146, 38514, 21683, 29245, 10197,
         5034,  1094,  2489, 17223,  3741,   530, 10788,  3420,   539,  2827,
         1724,   589, 17223, 38259,   518,  1012,   539,   518, 14836,   589,
        17223,   533,  1105,   633,  1400,  3027, 38514, 10033,   585,  4643,
          550,  5034,  1094,  1844, 14771,   593,  4044,  2540,   585,  2088,
          518,  1530,  5501,  8821,   537,  3721,   589, 17223,   533,   773,
        46642,   537,  3564, 10118,  4547,   805, 49407], dtype=torch.int32)
In [92]:
# Empiler les images en un seul tenseur
image_input = torch.stack(images).to(device)

# Encoder les images et les descriptions
with torch.no_grad():
    image_features = model.encode_image(image_input)
    text_features = model.encode_text(texts)

# Normaliser les caractéristiques
image_features /= image_features.norm(dim=-1, keepdim=True)
text_features /= text_features.norm(dim=-1, keepdim=True)

Combiner les caractéristiques des images et des textes¶

Combinez les caractéristiques encodées des images et des textes pour former une représentation conjointe.

In [93]:
# Combiner les caractéristiques des images et des textes
combined_features = torch.cat((image_features, text_features), dim=1).cpu().numpy()

Entraîner un classificateur¶

Utilisez les caractéristiques combinées pour entraîner un classificateur, comme une régression logistique.

In [94]:
# Diviser les données en ensembles d'entraînement et de test
X_train, X_test, y_train, y_test, train_indices, test_indices = train_test_split(
    combined_features, data_final['label'], data_final.index, 
    test_size=0.2, stratify=data_final['label'], random_state=seed_value)
# Vérifier la répartition des classes
check_class_distribution(y_train, y_test, label_to_category)
No description has been provided for this image
In [95]:
# Entraîner un classificateur
classifier = LogisticRegression(max_iter=1000)
classifier.fit(X_train, y_train)
Out[95]:
LogisticRegression(max_iter=1000)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
LogisticRegression(max_iter=1000)
In [96]:
time2 = time.time() - time1
minutes, seconds = divmod(time2, 60)
duration_str = f"{int(minutes)} min {int(seconds)} sec"

Évaluer le classificateur¶

In [97]:
print("Score d'entraînement :", classifier.score(X_train, y_train))
print("Score de test :", classifier.score(X_test, y_test))
Score d'entraînement : 0.9583333333333334
Score de test : 0.9571428571428572

TRAiN¶

In [98]:
y_train_pred_classes = get_predictions(classifier, X_train)
target_names = [label_to_category[label] for label in sorted(label_to_category)]
print(classification_report(y_train, y_train_pred_classes, target_names=target_names))
                            precision    recall  f1-score   support

                 baby care       0.95      0.85      0.90       120
  beauty and personal care       0.97      0.93      0.94       120
                 computers       0.98      1.00      0.99       120
home decor & festive needs       0.94      0.97      0.95       120
           home furnishing       0.91      0.97      0.94       120
          kitchen & dining       0.97      1.00      0.98       120
                   watches       1.00      0.99      1.00       120

                  accuracy                           0.96       840
                 macro avg       0.96      0.96      0.96       840
              weighted avg       0.96      0.96      0.96       840

In [99]:
conf_matrix_train = confusion_matrix(y_train, y_train_pred_classes)
plot_confusion_matrix(conf_matrix_train, 'TRAIN')
No description has been provided for this image

TEST¶

In [100]:
y_test_pred_classes = get_predictions(classifier, X_test)
target_names = [label_to_category[label] for label in sorted(label_to_category)]
print(classification_report(y_test, y_test_pred_classes, target_names=target_names))
                            precision    recall  f1-score   support

                 baby care       0.97      0.97      0.97        30
  beauty and personal care       0.96      0.83      0.89        30
                 computers       0.91      1.00      0.95        30
home decor & festive needs       0.88      0.93      0.90        30
           home furnishing       1.00      1.00      1.00        30
          kitchen & dining       1.00      0.97      0.98        30
                   watches       1.00      1.00      1.00        30

                  accuracy                           0.96       210
                 macro avg       0.96      0.96      0.96       210
              weighted avg       0.96      0.96      0.96       210

In [101]:
conf_matrix_test = confusion_matrix(y_test, y_test_pred_classes)
plot_confusion_matrix(conf_matrix_test, 'TEST')
No description has been provided for this image

Enregistrement des résultats¶

In [102]:
perf_test_df = pd.concat([perf_test_df, pd.DataFrame({'Scenario': ['TEST_CLIP_model_B'], 
                                                      'Description': ['AVEC tokenisation NLTK et troncature avec CLIP'], 
                                                      'Accuracy_Train': [classifier.score(X_train, y_train) *100],
                                                      'Accuracy_Test': [classifier.score(X_test, y_test) *100], 
                                                      'Durée_totale_computation': [duration_str]})], ignore_index=True)
perf_test_df
Out[102]:
Scenario Description Accuracy_Train Accuracy_Test Durée_totale_computation
0 Baseline_DenseNet121 AVEC poids imagenet & SANS data-augmentation 97.533631 88.607597 3 min 2 sec
1 TEST_CLIP_model_A SANS tokenisation NLTK et troncature avec CLIP... 96.547619 96.666667 2 min 40 sec
2 TEST_CLIP_model_B AVEC tokenisation NLTK et troncature avec CLIP 95.833333 95.714286 2 min 41 sec

Visualisation des images bien et mal classées sur le TEST¶

In [103]:
visualisation_images_TEST('BIEN', y_test, y_test_pred_classes, data_final, test_indices, dict_label=label_to_category, num_examples=6)
visualisation_images_TEST('MAL', y_test, y_test_pred_classes, data_final, test_indices, dict_label=label_to_category, num_examples=6)
No description has been provided for this image
No description has been provided for this image
In [104]:
perf_test_df
Out[104]:
Scenario Description Accuracy_Train Accuracy_Test Durée_totale_computation
0 Baseline_DenseNet121 AVEC poids imagenet & SANS data-augmentation 97.533631 88.607597 3 min 2 sec
1 TEST_CLIP_model_A SANS tokenisation NLTK et troncature avec CLIP... 96.547619 96.666667 2 min 40 sec
2 TEST_CLIP_model_B AVEC tokenisation NLTK et troncature avec CLIP 95.833333 95.714286 2 min 41 sec

CONCLUSIONS¶

RAPPEL SCORE DU MEILLEUR DENSENET

CONCLUSION MODÈLES CLIP MEILLEUR SANS TOKENISATION NLTK

  • MOINS COUTEUX QUE DENSENT SANS GPU